@MySQL 主从自动修复 - 复制错误
文章目录
- MySQL主从复制错误-自动修复
- 脚本功能
- 安全建议
- 脚本编写
- 使用说明
- 日志输出
MySQL主从复制错误-自动修复
根据您的需求,我优化了脚本,使其能够:
- 检查主从状态
- 从错误信息中提取GTID
- 自动跳过错误事务
- 循环处理直到所有错误解决
脚本功能
- 状态检查: 验证MySQL连接 检查Slave_IO_Running和Slave_SQL_Running状态 解析Last_SQL_Error中的错误信息
- 错误处理: 使用正则表达式从错误信息中提取GTID 自动执行STOP SLAVE, SET GTID_NEXT, BEGIN, COMMIT操作 处理完成后自动START SLAVE
- 循环机制: 每次处理后等待5秒重新检查状态 最多处理50个错误(可配置) 当所有错误解决且线程状态正常时自动退出
安全建议
-
创建专用MySQL用户:
CREATE USER 'repl_monitor'@'localhost' IDENTIFIED BY 'strong_password'; GRANT REPLICATION CLIENT, REPLICATION SLAVE ADMIN ON *.* TO 'repl_monitor'@'localhost';
-
在生产环境使用前充分测试
-
定期备份数据库
-
监控脚本执行日志
脚本编写
#!/bin/bash# MySQL连接配置
MYSQL_USER="root"
MYSQL_PASSWORD="your_password"
MYSQL_HOST="localhost"
MYSQL_PORT="3306"# 最大错误处理次数(防止无限循环)
MAX_ERRORS=50
ERROR_COUNT=0
SLEEP_TIME=5 # 每次检查间隔秒数# 检查MySQL连接
check_mysql_connection() {mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" -e "SELECT 1" >/dev/null 2>&1if [ $? -ne 0 ]; thenecho "ERROR: Failed to connect to MySQL server. Please check your credentials."exit 1fi
}# 获取主从状态信息
get_slave_status() {mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" -e "SHOW SLAVE STATUS\G" 2>/dev/null
}# 检查主从状态是否正常
check_replication_status() {local status_output=$(get_slave_status)# 检查IO和SQL线程状态local io_running=$(echo "$status_output" | grep "Slave_IO_Running:" | awk '{print $2}')local sql_running=$(echo "$status_output" | grep "Slave_SQL_Running:" | awk '{print $2}')# 检查是否有错误local last_error=$(echo "$status_output" | grep "Last_SQL_Error:" | sed 's/Last_SQL_Error: //')if [ "$io_running" = "Yes" ] && [ "$sql_running" = "Yes" ] && [ -z "$last_error" ]; thenreturn 0 # 状态正常elseecho "$status_output" # 返回状态输出用于解析return 1 # 状态异常fi
}# 从错误信息中提取GTID
extract_gtid_from_error() {local error_message="$1"# 使用正则表达式匹配GTID格式:UUID:序列号echo "$error_message" | grep -oE "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}:[0-9]+"
}# 跳过指定的GTID错误
skip_gtid_error() {local gtid="$1"echo "处理错误GTID: $gtid"mysql -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" -h"$MYSQL_HOST" -P"$MYSQL_PORT" <<EOFSTOP SLAVE;SET GTID_NEXT='$gtid';BEGIN; COMMIT;SET GTID_NEXT='AUTOMATIC';START SLAVE;
EOFif [ $? -ne 0 ]; thenecho "错误: 无法跳过GTID $gtid"return 1fireturn 0
}# 主处理循环
main() {check_mysql_connectionecho "开始监控MySQL主从复制状态..."while [ $ERROR_COUNT -lt $MAX_ERRORS ]; dostatus_output=$(check_replication_status)status_code=$?if [ $status_code -eq 0 ]; thenecho "主从复制状态正常"echo "脚本执行完成"exit 0fi# 提取错误信息last_error=$(echo "$status_output" | grep "Last_SQL_Error:" | sed 's/Last_SQL_Error: //')if [ -n "$last_error" ]; thenecho "检测到复制错误: $last_error"# 从错误信息中提取GTIDgtid=$(extract_gtid_from_error "$last_error")if [ -n "$gtid" ]; thenecho "提取到错误GTID: $gtid"skip_gtid_error "$gtid"if [ $? -eq 0 ]; then((ERROR_COUNT++))echo "已处理错误 #$ERROR_COUNT, 等待${SLEEP_TIME}秒后重新检查..."sleep $SLEEP_TIMEcontinueelseecho "错误: 无法修复GTID $gtid"exit 1fielseecho "警告: 在错误信息中未找到GTID"echo "请手动检查错误: $last_error"exit 1fielse# 检查线程状态io_running=$(echo "$status_output" | grep "Slave_IO_Running:" | awk '{print $2}')sql_running=$(echo "$status_output" | grep "Slave_SQL_Running:" | awk '{print $2}')if [ "$io_running" != "Yes" ] || [ "$sql_running" != "Yes" ]; thenecho "复制线程未运行: IO_Running=$io_running, SQL_Running=$sql_running"echo "请手动检查复制状态"exit 1fifisleep $SLEEP_TIMEdoneecho "错误: 已达到最大错误处理次数($MAX_ERRORS), 需要人工干预"exit 1
}# 执行主函数
main
使用说明
-
配置MySQL连接参数:
MYSQL_USER="root" MYSQL_PASSWORD="your_password" MYSQL_HOST="localhost" MYSQL_PORT="3306"
-
设置脚本权限:
chmod +x mysql_replication_fixer.sh
-
执行脚本:
./mysql_replication_fixer.sh
日志输出
开始监控MySQL主从复制状态...
检测到复制错误: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '3669c25f-587d-11f0-b026-005056865fd6:90707229' at source log zbx-db1.000099, end_log_pos 673717022. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
提取到错误GTID: 3669c25f-587d-11f0-b026-005056865fd6:90707229
处理错误GTID: 3669c25f-587d-11f0-b026-005056865fd6:90707229
已处理错误 #1, 等待5秒后重新检查...
主从复制状态正常
脚本执行完成
这个脚本能够自动处理您描述的复制错误场景,并在修复所有错误后正常退出。- 生产环境慎用