最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux使用pt-slave-restart監(jiān)控多個(gè)從庫的Shell腳本案例

 更新時(shí)間:2025年10月22日 09:21:18   作者:學(xué)亮編程手記  
本文介紹了如何編寫并使用一個(gè)基于pt-slave-restart的Shell腳本,實(shí)現(xiàn)對(duì)多個(gè)MySQL從庫復(fù)制狀態(tài)的靈活監(jiān)控,支持多種配置方式、參數(shù)覆蓋、錯(cuò)誤處理及守護(hù)進(jìn)程等功能,便于高效管理數(shù)據(jù)庫復(fù)制,需要的朋友可以參考下

我來為您編寫一個(gè)使用pt-slave-restart監(jiān)控多個(gè)從庫的Shell腳本,支持靈活的傳參功能。

腳本代碼

#!/bin/bash

# pt-slave-restart監(jiān)控腳本
# 用于監(jiān)控多個(gè)MySQL從庫的復(fù)制狀態(tài)并在出錯(cuò)時(shí)自動(dòng)重啟

# 默認(rèn)配置
DEFAULT_USER="monitor_user"
DEFAULT_SOCKET="/tmp/mysql.sock"
DEFAULT_ERRORS="1062,1032,1205,1158,1159,1007,1008,1050,1051,1054,1060,1061,1094,1213,1169,1232"
DEFAULT_MAX_CYCLE=10
DEFAULT_SLEEP=300
DEFAULT_LOG_FILE="/var/log/pt-slave-restart.log"
CONFIG_FILE="/etc/pt-slave-restart.conf"

# 顯示用法
usage() {
    cat << EOF
用法: $0 [選項(xiàng)] [實(shí)例...]

選項(xiàng):
    -u, --user USER         MySQL用戶名 (默認(rèn): $DEFAULT_USER)
    -p, --password PASS     MySQL密碼
    -S, --socket SOCKET     默認(rèn)socket文件 (默認(rèn): $DEFAULT_SOCKET)
    -h, --host HOST         主機(jī)名 (默認(rèn)使用socket)
    -P, --port PORT         端口號(hào)
    -e, --errors ERRORS     跳過的錯(cuò)誤代碼 (默認(rèn): $DEFAULT_ERRORS)
    -m, --max-cycle CYCLE   最大重啟循環(huán)次數(shù) (默認(rèn): $DEFAULT_MAX_CYCLE)
    -s, --sleep SECONDS     檢查間隔秒數(shù) (默認(rèn): $DEFAULT_SLEEP)
    -l, --log FILE          日志文件 (默認(rèn): $DEFAULT_LOG_FILE)
    -c, --config FILE       配置文件 (默認(rèn): $CONFIG_FILE)
    -d, --daemon            以守護(hù)進(jìn)程模式運(yùn)行
    -v, --verbose           詳細(xì)輸出
    --help                  顯示此幫助信息

實(shí)例格式:
    host:port:socket:user:password
    host:port
    socket
    別名 (需要在配置文件中定義)

配置文件格式 ($CONFIG_FILE):
    # 每行定義一個(gè)MySQL實(shí)例
    # 格式: 別名|host:port|user|password|socket
    slave1|192.168.1.101:3306|monitor|password123|/tmp/mysql1.sock
    slave2|192.168.1.102:3307|monitor|password123|/tmp/mysql2.sock
    slave3||monitor|password123|/tmp/mysql3.sock

示例:
    $0 -u monitor -p pass123 slave1 slave2
    $0 -d -s 60 192.168.1.101:3306 /tmp/mysql.sock
    $0 --verbose --errors "1062,1032" slave1
EOF
}

# 日志函數(shù)
log() {
    local level=$1
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
    
    if [[ "$VERBOSE" == "true" && "$level" != "DEBUG" ]]; then
        echo "[$timestamp] [$level] $message"
    fi
}

# 讀取配置文件
read_config() {
    local alias=$1
    if [[ -f "$CONFIG_FILE" ]]; then
        while IFS='|' read -r config_alias config_host_port config_user config_password config_socket; do
            if [[ "$config_alias" == "$alias" ]]; then
                HOST=${config_host_port%:*}
                PORT=${config_host_port#*:}
                USER=$config_user
                PASSWORD=$config_password
                SOCKET=$config_socket
                return 0
            fi
        done < <(grep -v '^#' "$CONFIG_FILE" | grep -v '^$')
    fi
    return 1
}

# 解析實(shí)例參數(shù)
parse_instance() {
    local instance=$1
    local parsed_host parsed_port parsed_socket parsed_user parsed_password
    
    # 重置為默認(rèn)值
    parsed_host=$HOST
    parsed_port=$PORT
    parsed_socket=$SOCKET
    parsed_user=$USER
    parsed_password=$PASSWORD
    
    # 檢查是否是配置文件中定義的別名
    if read_config "$instance"; then
        return 0
    fi
    
    # 解析 host:port:socket:user:password 格式
    if [[ "$instance" =~ : ]]; then
        IFS=':' read -r -a parts <<< "$instance"
        case ${#parts[@]} in
            2)
                parsed_host=${parts[0]}
                parsed_port=${parts[1]}
                parsed_socket=""
                ;;
            3)
                parsed_host=${parts[0]}
                parsed_port=${parts[1]}
                parsed_socket=${parts[2]}
                ;;
            4)
                parsed_host=${parts[0]}
                parsed_port=${parts[1]}
                parsed_socket=${parts[2]}
                parsed_user=${parts[3]}
                ;;
            5)
                parsed_host=${parts[0]}
                parsed_port=${parts[1]}
                parsed_socket=${parts[2]}
                parsed_user=${parts[3]}
                parsed_password=${parts[4]}
                ;;
            *)
                log "ERROR" "無效的實(shí)例格式: $instance"
                return 1
                ;;
        esac
    else
        # 如果只提供socket路徑
        if [[ "$instance" =~ \.sock ]]; then
            parsed_socket=$instance
            parsed_host=""
            parsed_port=""
        else
            # 嘗試作為別名從配置文件中讀取
            if ! read_config "$instance"; then
                log "ERROR" "未知的實(shí)例別名且不是有效的socket路徑: $instance"
                return 1
            fi
        fi
    fi
    
    HOST=$parsed_host
    PORT=$parsed_port
    SOCKET=$parsed_socket
    USER=$parsed_user
    PASSWORD=$parsed_password
}

# 構(gòu)建連接參數(shù)
build_connection_args() {
    local connect_args=""
    
    if [[ -n "$SOCKET" ]]; then
        connect_args="--socket=$SOCKET"
    elif [[ -n "$HOST" && -n "$PORT" ]]; then
        connect_args="--host=$HOST --port=$PORT"
    elif [[ -n "$HOST" ]]; then
        connect_args="--host=$HOST"
        if [[ -n "$PORT" ]]; then
            connect_args="$connect_args --port=$PORT"
        fi
    else
        connect_args="--socket=$DEFAULT_SOCKET"
    fi
    
    if [[ -n "$USER" ]]; then
        connect_args="$connect_args --user=$USER"
    fi
    
    if [[ -n "$PASSWORD" ]]; then
        connect_args="$connect_args --password=$PASSWORD"
    fi
    
    echo "$connect_args"
}

# 監(jiān)控單個(gè)實(shí)例
monitor_instance() {
    local instance_name=$1
    local connect_args=$2
    
    log "INFO" "開始監(jiān)控實(shí)例: $instance_name"
    
    local pt_command="pt-slave-restart $connect_args"
    pt_command="$pt_command --error-numbers=$ERRORS"
    pt_command="$pt_command --max-cycle=$MAX_CYCLE"
    pt_command="$pt_command --sleep=$SLEEP"
    pt_command="$pt_command --log=$LOG_FILE"
    pt_command="$pt_command --verbose"
    pt_command="$pt_command --skip-count=0"
    pt_command="$pt_command --always"
    
    if [[ "$DAEMON" == "true" ]]; then
        pt_command="$pt_command --daemonize"
        log "INFO" "以守護(hù)進(jìn)程模式啟動(dòng): $pt_command"
        eval $pt_command
    else
        log "INFO" "執(zhí)行命令: $pt_command"
        eval $pt_command
    fi
    
    local exit_code=$?
    if [[ $exit_code -eq 0 ]]; then
        log "INFO" "實(shí)例 $instance_name 監(jiān)控啟動(dòng)成功"
    else
        log "ERROR" "實(shí)例 $instance_name 監(jiān)控啟動(dòng)失敗,退出碼: $exit_code"
    fi
    
    return $exit_code
}

# 主函數(shù)
main() {
    # 設(shè)置默認(rèn)值
    USER=$DEFAULT_USER
    SOCKET=$DEFAULT_SOCKET
    ERRORS=$DEFAULT_ERRORS
    MAX_CYCLE=$DEFAULT_MAX_CYCLE
    SLEEP=$DEFAULT_SLEEP
    LOG_FILE=$DEFAULT_LOG_FILE
    DAEMON="false"
    VERBOSE="false"
    
    # 解析命令行參數(shù)
    while [[ $# -gt 0 ]]; do
        case $1 in
            -u|--user)
                USER="$2"
                shift 2
                ;;
            -p|--password)
                PASSWORD="$2"
                shift 2
                ;;
            -S|--socket)
                SOCKET="$2"
                shift 2
                ;;
            -h|--host)
                HOST="$2"
                shift 2
                ;;
            -P|--port)
                PORT="$2"
                shift 2
                ;;
            -e|--errors)
                ERRORS="$2"
                shift 2
                ;;
            -m|--max-cycle)
                MAX_CYCLE="$2"
                shift 2
                ;;
            -s|--sleep)
                SLEEP="$2"
                shift 2
                ;;
            -l|--log)
                LOG_FILE="$2"
                shift 2
                ;;
            -c|--config)
                CONFIG_FILE="$2"
                shift 2
                ;;
            -d|--daemon)
                DAEMON="true"
                shift
                ;;
            -v|--verbose)
                VERBOSE="true"
                shift
                ;;
            --help)
                usage
                exit 0
                ;;
            -*)
                echo "未知選項(xiàng): $1"
                usage
                exit 1
                ;;
            *)
                break
                ;;
        esac
    done
    
    # 檢查是否安裝了pt-slave-restart
    if ! command -v pt-slave-restart &> /dev/null; then
        echo "錯(cuò)誤: 未找到 pt-slave-restart 命令,請(qǐng)先安裝 Percona Toolkit"
        exit 1
    fi
    
    # 獲取實(shí)例列表
    if [[ $# -eq 0 ]]; then
        # 如果沒有提供實(shí)例參數(shù),從配置文件讀取所有實(shí)例
        if [[ -f "$CONFIG_FILE" ]]; then
            instances=()
            while IFS='|' read -r alias host_port user password socket; do
                if [[ -n "$alias" && ! "$alias" =~ ^# ]]; then
                    instances+=("$alias")
                fi
            done < <(grep -v '^#' "$CONFIG_FILE" | grep -v '^$')
            
            if [[ ${#instances[@]} -eq 0 ]]; then
                echo "錯(cuò)誤: 配置文件中沒有定義實(shí)例,且未提供實(shí)例參數(shù)"
                usage
                exit 1
            fi
        else
            echo "錯(cuò)誤: 未提供實(shí)例參數(shù)且配置文件不存在: $CONFIG_FILE"
            usage
            exit 1
        fi
    else
        instances=("$@")
    fi
    
    log "INFO" "開始監(jiān)控 ${#instances[@]} 個(gè)實(shí)例"
    log "INFO" "跳過錯(cuò)誤代碼: $ERRORS"
    log "INFO" "最大重啟循環(huán): $MAX_CYCLE"
    log "INFO" "檢查間隔: $SLEEP 秒"
    log "INFO" "日志文件: $LOG_FILE"
    
    # 監(jiān)控每個(gè)實(shí)例
    for instance in "${instances[@]}"; do
        # 保存原始值
        original_host=$HOST
        original_port=$PORT
        original_socket=$SOCKET
        original_user=$USER
        original_password=$PASSWORD
        
        # 解析實(shí)例參數(shù)
        if ! parse_instance "$instance"; then
            log "ERROR" "解析實(shí)例失敗: $instance"
            continue
        fi
        
        # 構(gòu)建連接參數(shù)
        connect_args=$(build_connection_args)
        
        # 生成實(shí)例顯示名稱
        if [[ -n "$SOCKET" ]]; then
            instance_name="socket:$SOCKET"
        elif [[ -n "$HOST" && -n "$PORT" ]]; then
            instance_name="$HOST:$PORT"
        else
            instance_name="$instance"
        fi
        
        # 啟動(dòng)監(jiān)控
        monitor_instance "$instance_name" "$connect_args" &
        
        # 恢復(fù)原始值
        HOST=$original_host
        PORT=$original_port
        SOCKET=$original_socket
        USER=$original_user
        PASSWORD=$original_password
    done
    
    # 如果不是守護(hù)進(jìn)程模式,等待所有子進(jìn)程
    if [[ "$DAEMON" == "false" ]]; then
        wait
    else
        log "INFO" "所有監(jiān)控進(jìn)程已在后臺(tái)啟動(dòng)"
    fi
}

# 運(yùn)行主函數(shù)
main "$@"

配置文件示例

創(chuàng)建配置文件 /etc/pt-slave-restart.conf

# 格式: 別名|host:port|user|password|socket
slave1|192.168.1.101:3306|monitor|password123|/tmp/mysql1.sock
slave2|192.168.1.102:3307|monitor|password123|/tmp/mysql2.sock
slave3||monitor|password123|/tmp/mysql3.sock
slave4|192.168.1.104:3306|monitor|password123|

使用示例

1. 基本用法

# 使用配置文件中的實(shí)例
./pt-slave-monitor.sh slave1 slave2

# 直接指定實(shí)例
./pt-slave-monitor.sh 192.168.1.101:3306 /tmp/mysql.sock

2. 指定連接參數(shù)

# 指定用戶名和密碼
./pt-slave-monitor.sh -u monitor -p password123 slave1 slave2

# 指定錯(cuò)誤代碼和檢查間隔
./pt-slave-monitor.sh -e "1062,1032" -s 60 slave1

3. 守護(hù)進(jìn)程模式

# 后臺(tái)運(yùn)行
./pt-slave-monitor.sh -d -l /var/log/mysql-monitor.log slave1 slave2 slave3

4. 詳細(xì)輸出

# 顯示詳細(xì)日志
./pt-slave-monitor.sh -v --errors "1062,1032,1205" slave1

腳本特點(diǎn)

  1. 靈活的實(shí)例定義:支持別名、host:port、socket等多種格式
  2. 配置文件支持:可以預(yù)定義實(shí)例配置
  3. 參數(shù)覆蓋:命令行參數(shù)可以覆蓋配置文件中的設(shè)置
  4. 錯(cuò)誤處理:完善的錯(cuò)誤處理和日志記錄
  5. 守護(hù)進(jìn)程模式:支持后臺(tái)運(yùn)行
  6. 多實(shí)例監(jiān)控:同時(shí)監(jiān)控多個(gè)從庫實(shí)例
  7. 自定義錯(cuò)誤代碼:可配置需要跳過的復(fù)制錯(cuò)誤

安裝和使用步驟

  1. 保存腳本為 pt-slave-monitor.sh
  2. 添加執(zhí)行權(quán)限:chmod +x pt-slave-monitor.sh
  3. 創(chuàng)建配置文件(可選)
  4. 安裝Percona Toolkit:yum install percona-toolkit 或 apt-get install percona-toolkit
  5. 運(yùn)行腳本監(jiān)控從庫

這個(gè)腳本提供了靈活的配置選項(xiàng)和強(qiáng)大的監(jiān)控功能,可以方便地管理多個(gè)MySQL從庫的復(fù)制狀態(tài)監(jiān)控。

以上就是Linux使用pt-slave-restart監(jiān)控多個(gè)從庫的Shell腳本案例的詳細(xì)內(nèi)容,更多關(guān)于Linux t-slave-restart監(jiān)控從庫的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Centos7添加靜態(tài)路由的方法

    Centos7添加靜態(tài)路由的方法

    本篇文章主要介紹了Centos7添加靜態(tài)路由的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • Gunicorn運(yùn)行與配置方法

    Gunicorn運(yùn)行與配置方法

    這篇文章主要介紹了Gunicorn運(yùn)行與配置方法,使用pre-fork worker模式,具有使用非常簡單,輕量級(jí)的資源消耗,以及高性能等特點(diǎn)。對(duì)此感興趣的朋友跟隨小編一起看看吧
    2019-08-08
  • Linux下的進(jìn)程控制解讀

    Linux下的進(jìn)程控制解讀

    這篇文章主要介紹了Linux下的進(jìn)程控制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Apache Hadoop版本詳解

    Apache Hadoop版本詳解

    本文總結(jié)了ApacheHadoop和Cloudera Hadoop的版本衍化過程,并給出了選擇Hadoop版本的一些建議。感興趣的朋友一起看看吧
    2017-09-09
  • Ubuntu上使用Netdata設(shè)置實(shí)時(shí)性能監(jiān)控的詳細(xì)流程

    Ubuntu上使用Netdata設(shè)置實(shí)時(shí)性能監(jiān)控的詳細(xì)流程

    Netdata通過可擴(kuò)展的Web儀表板提供準(zhǔn)確的性能監(jiān)控,可以顯示Linux系統(tǒng)上的流程和服務(wù)。這篇文章給大家介紹Ubuntu上使用Netdata設(shè)置實(shí)時(shí)性能監(jiān)控的流程,感興趣的朋友一起看看吧
    2018-08-08
  • Linux日志查看和分析過程

    Linux日志查看和分析過程

    Linux日志是系統(tǒng)運(yùn)行狀態(tài)的重要記錄,包括系統(tǒng)啟動(dòng)、服務(wù)運(yùn)行、用戶操作和安全事件等信息,對(duì)于故障排查、安全審計(jì)和系統(tǒng)維護(hù)至關(guān)重要,文章詳細(xì)介紹了Linux日志的主要類型、存儲(chǔ)位置及作用,并提供了常用的查看和分析命令及工具
    2026-01-01
  • Linux設(shè)置虛擬內(nèi)存的教學(xué)與實(shí)戰(zhàn)教程

    Linux設(shè)置虛擬內(nèi)存的教學(xué)與實(shí)戰(zhàn)教程

    這篇文章主要給大家介紹了關(guān)于Linux設(shè)置虛擬內(nèi)存教學(xué)與實(shí)戰(zhàn)的相關(guān)資料,文中通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 服務(wù)器安裝寶塔面板無法遠(yuǎn)程連接數(shù)據(jù)庫的解決方法

    服務(wù)器安裝寶塔面板無法遠(yuǎn)程連接數(shù)據(jù)庫的解決方法

    這篇文章主要介紹了服務(wù)器安裝寶塔面板無法遠(yuǎn)程連接數(shù)據(jù)庫的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Ubuntu VPS 簡易安裝LAMP教程

    Ubuntu VPS 簡易安裝LAMP教程

    LAMP是Linux、Apache、MySQL和PHP的首字母縮寫詞,本教程將引導(dǎo)你安裝基于Ubuntu10.10系統(tǒng)的Apache2服務(wù)器,支持PHP5(mod_php)和MySQL。
    2011-02-02
  • 如何對(duì)安裝Linux的服務(wù)器進(jìn)行緩存清除

    如何對(duì)安裝Linux的服務(wù)器進(jìn)行緩存清除

    這篇文章主要介紹了如何對(duì)安裝Linux的服務(wù)器進(jìn)行緩存清除問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評(píng)論

个旧市| 武穴市| 霍州市| 扎囊县| 民丰县| 诸暨市| 香港| 苏尼特左旗| 博野县| 通州市| 太原市| 伊春市| 台湾省| 宜宾市| 米泉市| 逊克县| 哈尔滨市| 东丰县| 巴林左旗| 庆元县| 河西区| 车致| 呈贡县| 沂源县| 西华县| 红河县| 磐安县| 临沧市| 文安县| 内丘县| 西峡县| 桐乡市| 永登县| 磐安县| 开平市| 永吉县| 纳雍县| 济宁市| 吉林市| 涪陵区| 抚远县|