自动配置MySQL主从复制的脚本

wen 实用脚本 1

本文目录导读:

自动配置MySQL主从复制的脚本

  1. 脚本代码
  2. 使用说明
  3. 注意事项

我来提供一个自动配置MySQL主从复制的Shell脚本,这个脚本可以自动配置主库和从库。

脚本代码

#!/bin/bash
# MySQL主从复制自动配置脚本
# 使用方法: 
#   主库: ./mysql_replication.sh master
#   从库: ./mysql_replication.sh slave master_ip
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 配置参数 - 请根据实际情况修改
MYSQL_ROOT_PASSWORD="your_root_password"  # MySQL root密码
REPLICATION_USER="repl"                    # 复制用户
REPLICATION_PASSWORD="repl_password"       # 复制用户密码
MYSQL_DATA_DIR="/var/lib/mysql"            # MySQL数据目录
MYSQL_CONF_DIR="/etc/mysql/mysql.conf.d"   # MySQL配置目录
BINLOG_FILE=""                             # 主库binlog文件名(从库使用)
BINLOG_POS=0                               # 主库binlog位置(从库使用)
# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}
log_warn() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}
# 检查是否为root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "请使用root用户运行此脚本"
        exit 1
    fi
}
# 检查MySQL是否安装
check_mysql() {
    if ! command -v mysql &> /dev/null; then
        log_error "MySQL未安装,请先安装MySQL"
        exit 1
    fi
    if ! systemctl is-active --quiet mysql; then
        log_error "MySQL服务未运行"
        exit 1
    fi
}
# 检查防火墙是否阻止MySQL连接
check_firewall() {
    if command -v ufw &> /dev/null; then
        ufw status | grep -q "active" && {
            log_warn "防火墙已开启,请确保端口3306已开放"
            echo "  执行: ufw allow 3306"
        }
    fi
}
# 配置主库
configure_master() {
    log_info "开始配置MySQL主库..."
    # 创建配置备份
    local conf_file="${MYSQL_CONF_DIR}/mysql.cnf"
    if [[ ! -f "$conf_file" ]]; then
        conf_file="/etc/mysql/my.cnf"
    fi
    cp "$conf_file" "${conf_file}.backup.$(date +%Y%m%d_%H%M%S)"
    # 检查是否已配置
    if grep -q "server-id" "$conf_file"; then
        log_warn "server-id已配置,跳过配置添加"
    else
        # 添加主库配置
        cat >> "$conf_file" << EOF
# 主从复制配置
[mysqld]
# 主从复制配置
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = your_database_name  # 需要复制的数据库,多个用空格分隔
binlog_ignore_db = mysql           # 不需要复制的数据库
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema
binlog_ignore_db = sys
# 可选配置
expire_logs_days = 7
max_binlog_size = 100M
binlog_format = ROW
EOF
    fi
    # 重启MySQL服务
    log_info "重启MySQL服务..."
    systemctl restart mysql
    sleep 3
    # 创建复制用户
    log_info "创建复制用户..."
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" << EOF
CREATE USER IF NOT EXISTS '${REPLICATION_USER}'@'%' IDENTIFIED BY '${REPLICATION_PASSWORD}';
GRANT REPLICATION SLAVE ON *.* TO '${REPLICATION_USER}'@'%';
FLUSH PRIVILEGES;
EOF
    # 获取主库状态
    log_info "获取主库状态..."
    local master_status=$(mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SHOW MASTER STATUS\G" 2>/dev/null)
    local binlog_file=$(echo "$master_status" | grep "File:" | awk '{print $2}')
    local binlog_pos=$(echo "$master_status" | grep "Position:" | awk '{print $2}')
    log_info "主库配置完成!"
    log_info "== 主库状态信息 =="
    log_info "Binlog文件: ${binlog_file}"
    log_info "Binlog位置: ${binlog_pos}"
    log_info "复制用户: ${REPLICATION_USER}"
    log_info "复制密码: ${REPLICATION_PASSWORD}"
    echo ""
    log_info "请在从库上执行以下命令:"
    echo "  $0 slave ${MASTER_IP}"
    echo ""
    log_info "或手动配置从库:"
    echo "  CHANGE MASTER TO"
    echo "    MASTER_HOST='${MASTER_IP}',"
    echo "    MASTER_USER='${REPLICATION_USER}',"
    echo "    MASTER_PASSWORD='${REPLICATION_PASSWORD}',"
    echo "    MASTER_LOG_FILE='${binlog_file}',"
    echo "    MASTER_LOG_POS=${binlog_pos};"
}
# 配置从库
configure_slave() {
    local master_ip=$1
    if [[ -z "$master_ip" ]]; then
        log_error "请提供主库IP地址"
        echo "使用方法: $0 slave master_ip_address"
        exit 1
    fi
    log_info "开始配置MySQL从库..."
    log_info "主库IP: ${master_ip}"
    # 创建配置备份
    local conf_file="${MYSQL_CONF_DIR}/mysql.cnf"
    if [[ ! -f "$conf_file" ]]; then
        conf_file="/etc/mysql/my.cnf"
    fi
    cp "$conf_file" "${conf_file}.backup.$(date +%Y%m%d_%H%M%S)"
    # 检查是否已配置
    if grep -q "server-id" "$conf_file"; then
        log_warn "server-id已配置,跳过配置添加"
    else
        # 生成随机server-id
        local server_id=$((RANDOM % 100 + 2))
        # 添加从库配置
        cat >> "$conf_file" << EOF
# 主从复制配置
[mysqld]
# 主从复制配置
server-id = ${server_id}
relay-log = /var/log/mysql/mysql-relay-bin.log
log_bin = /var/log/mysql/mysql-bin.log
binlog_do_db = your_database_name  # 需要复制的数据库,与主库一致
# 可选配置
read_only = 1
skip-slave-start = 0
slave-skip-errors = 1062,1032,1452
EOF
    fi
    # 重启MySQL服务
    log_info "重启MySQL服务..."
    systemctl restart mysql
    sleep 3
    # 配置复制
    log_info "配置主从复制..."
    # 如果提供了binlog信息,使用提供的;否则从主库获取
    if [[ -n "$BINLOG_FILE" && "$BINLOG_POS" -gt 0 ]]; then
        log_info "使用提供的binlog信息"
    else
        # 尝试从主库获取状态
        log_info "尝试从主库获取binlog信息..."
        local master_status=$(mysql -u root -p"${MYSQL_ROOT_PASSWORD}" \
            -h "${master_ip}" \
            -e "SHOW MASTER STATUS\G" 2>/dev/null)
        if [[ $? -eq 0 ]]; then
            BINLOG_FILE=$(echo "$master_status" | grep "File:" | awk '{print $2}')
            BINLOG_POS=$(echo "$master_status" | grep "Position:" | awk '{print $2}')
        else
            log_error "无法从主库获取binlog信息"
            log_info "请在主库执行: SHOW MASTER STATUS;"
            read -p "请输入Binlog文件名: " BINLOG_FILE
            read -p "请输入Binlog位置: " BINLOG_POS
        fi
    fi
    # 停止之前的复制
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "STOP SLAVE;" 2>/dev/null || true
    # 配置主从复制
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" << EOF
CHANGE MASTER TO
    MASTER_HOST='${master_ip}',
    MASTER_USER='${REPLICATION_USER}',
    MASTER_PASSWORD='${REPLICATION_PASSWORD}',
    MASTER_LOG_FILE='${BINLOG_FILE}',
    MASTER_LOG_POS=${BINLOG_POS},
    MASTER_CONNECT_RETRY=10;
START SLAVE;
EOF
    sleep 2
    # 检查复制状态
    log_info "检查复制状态..."
    local slave_status=$(mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SHOW SLAVE STATUS\G" 2>/dev/null)
    local slave_io=$(echo "$slave_status" | grep "Slave_IO_Running:" | awk '{print $2}')
    local slave_sql=$(echo "$slave_status" | grep "Slave_SQL_Running:" | awk '{print $2}')
    local seconds_behind=$(echo "$slave_status" | grep "Seconds_Behind_Master:" | awk '{print $2}')
    if [[ "$slave_io" == "Yes" && "$slave_sql" == "Yes" ]]; then
        log_info "主从复制配置成功!"
        log_info "IO线程状态: ${slave_io}"
        log_info "SQL线程状态: ${slave_sql}"
        log_info "延迟: ${seconds_behind}秒"
    else
        log_error "主从复制配置可能存在问题"
        log_info "IO线程状态: ${slave_io}"
        log_info "SQL线程状态: ${slave_sql}"
        local last_error=$(echo "$slave_status" | grep "Last_Error:" | awk '{print $2}')
        if [[ -n "$last_error" ]]; then
            log_error "错误信息: ${last_error}"
        fi
    fi
}
# 检查复制状态
check_status() {
    log_info "检查主从复制状态..."
    # 检查主库状态
    log_info "=== 主库状态 ==="
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SHOW MASTER STATUS\G" 2>/dev/null || log_error "无法获取主库状态"
    # 检查从库状态
    log_info "=== 从库状态 ==="
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "SHOW SLAVE STATUS\G" 2>/dev/null || log_error "无法获取从库状态"
}
# 停止复制
stop_replication() {
    log_info "停止主从复制..."
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "STOP SLAVE;" 2>/dev/null || true
    log_info "复制已停止"
}
# 启动复制
start_replication() {
    log_info "启动主从复制..."
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "START SLAVE;" 2>/dev/null || true
    log_info "复制已启动"
}
# 重置复制
reset_replication() {
    log_info "重置主从复制..."
    mysql -u root -p"${MYSQL_ROOT_PASSWORD}" -e "STOP SLAVE; RESET SLAVE;" 2>/dev/null || true
    log_info "复制已重置"
}
# 显示帮助信息
show_help() {
    echo "MySQL主从复制自动配置脚本"
    echo ""
    echo "使用方法:"
    echo "  $0 master                    - 配置为主库"
    echo "  $0 slave master_ip           - 配置为从库"
    echo "  $0 status                    - 检查复制状态"
    echo "  $0 start                     - 启动复制"
    echo "  $0 stop                      - 停止复制"
    echo "  $0 reset                     - 重置复制"
    echo "  $0 help                      - 显示帮助信息"
    echo ""
    echo "示例:"
    echo "  $0 master                    # 在主库上执行"
    echo "  $0 slave 192.168.1.100       # 在从库上执行"
}
# 主函数
main() {
    check_root
    check_mysql
    check_firewall
    case "$1" in
        master)
            configure_master
            ;;
        slave)
            configure_slave "$2"
            ;;
        status)
            check_status
            ;;
        start)
            start_replication
            ;;
        stop)
            stop_replication
            ;;
        reset)
            reset_replication
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            log_error "未知命令: $1"
            show_help
            exit 1
            ;;
    esac
}
# 执行主函数
main "$@"

使用说明

保存脚本

将上述脚本保存为 mysql_replication.sh

添加执行权限

chmod +x mysql_replication.sh

在主库上执行

# 在主库服务器上运行
./mysql_replication.sh master

在从库上执行

# 在从库服务器上运行,替换master_ip为主库的实际IP
./mysql_replication.sh slave 192.168.1.100

其他管理命令

# 检查复制状态
./mysql_replication.sh status
# 停止复制
./mysql_replication.sh stop
# 启动复制
./mysql_replication.sh start
# 重置复制
./mysql_replication.sh reset
# 查看帮助
./mysql_replication.sh help

注意事项

  1. 修改配置参数:脚本开头的 MYSQL_ROOT_PASSWORD 等变量需要根据实际情况修改

  2. 数据库权限:确保复制用户有足够的权限

  3. 网络连通性:确保主从库之间网络互通,防火墙允许3306端口

  4. 数据一致性:配置前需要确保主从库数据一致

  5. 配置文件路径:不同发行版可能路径不同,根据实际情况修改

  6. MySQL版本:建议主从库使用相同版本的MySQL

这个脚本会自动完成大部分配置工作,但在生产环境中使用前请仔细测试。

抱歉,评论功能暂时关闭!