新增备份脚本backup-sync.sh和还原脚本restore-sync.sh,用于处理严重复制冲突场景 更新故障分析文档,补充全量备份还原的操作流程和注意事项 添加测试流程模板文件_TEST_FLOW_TEMPLATE.md 更新SKILL.md文档,增加测试流程分析相关内容
7.8 KiB
MySQL 8.4 复制冲突解决指南
AI 响应规范 (MySQL 执行策略):
- 强制参数: 所有
docker exec命令必须包含-h127.0.0.1参数。- 双重输出: 涉及 SQL 操作时,必须同时输出
Docker 执行命令和纯 SQL 脚本。- 默认连接: 默认使用
-uroot -pafe123456 -h127.0.0.1。- 排障连贯性: 诊断复制冲突时,在提供 A. 查看复制状态概要 后,必须紧跟 提供 B. 自动提取错误详情 脚本,以便用户直接获取修复建议。
1. 复制冲突解决(主键/唯一键重复或记录缺失)
1.1 快速定位冲突信息
当复制中断时,必须按顺序执行以下两步:首先查看概要,然后提取详细错误以获取修复脚本。
A. 查看复制状态概要:
# 方式 1: 传统状态查看 (重点关注 Last_SQL_Error)
docker exec -it mysql mysql -uroot -pafe123456 -h127.0.0.1 -e "SHOW REPLICA STATUS\G" | grep -E "Replica_.*_Running|Last_SQL_Error|Retrieved_Gtid_Set|Executed_Gtid_Set"
# 方式 2: 多线程环境下查看详情 (若启用并行复制,SHOW REPLICA STATUS 只能看到协调线程错误)
docker exec -it mysql mysql -uroot -pafe123456 -h127.0.0.1 -e "SELECT * FROM performance_schema.replication_applier_status_by_worker WHERE LAST_ERROR_NUMBER > 0\G"
B. 自动提取错误详情(支持 1062 重复键 / 1032 记录未找到): 直接在宿主机执行以下脚本,它会自动解析错误日志并生成对应的修复方案:
# 提取冲突 GTID、表、冲突值及修复建议
grep -aE "Duplicate entry|Error_code: 1032" /data/mysql/logs/mysql_error.log | perl -nle '
if (/^(\S+).*?transaction\s+[\x27"]([^\x27"]+)[\x27"].*?table\s+([^\s;]+);/) {
my ($time, $gtid, $table) = ($1, $2, $3);
print "\n" . "="x60;
print "时间: $time";
print "GTID: $gtid";
print "表名: $table";
if (/Duplicate entry\s+[\x27"]([^\x27"]+)[\x27"]\s+for\s+key\s+[\x27"]([^\x27"]+)[\x27"]/) {
print "类型: 1062 (主键/唯一键重复)";
print "冲突值: $1 (索引: $2)";
print "\n方案 A (手动修复 - 删除从库冲突行):";
print "DELETE FROM $table WHERE [主键列] = \x27$1\x27;";
print "\n方案 B (跳过事务 - 保持从库现状):";
print "STOP REPLICA; SET GTID_NEXT=\x27$gtid\x27; BEGIN; COMMIT; SET GTID_NEXT=\x27AUTOMATIC\x27; START REPLICA;";
} elsif (/Error_code: 1032|HA_ERR_KEY_NOT_FOUND/) {
print "类型: 1032 (记录未找到 - 通常是 Delete/Update 目标不存在)";
print "说明: 目标行在从库已不存在,Delete 操作已实质生效。";
print "\n方案 A (直接跳过 - 安全):";
print "STOP REPLICA; SET GTID_NEXT=\x27$gtid\x27; BEGIN; COMMIT; SET GTID_NEXT=\x27AUTOMATIC\x27; START REPLICA;";
}
}
'
1.2 安全修复冲突(推荐删除冲突数据)
停止复制,临时关闭 binlog(避免删除操作同步到对端):
A. Docker 执行模式 (包含 -h127.0.0.1):
# 以实际冲突表和主键为例(示例:test_sync.t1 的 id=12)
docker exec -it mysql mysql -uroot -pafe123456 -h127.0.0.1 -e "
STOP REPLICA;
SET sql_log_bin = OFF;
DELETE FROM `test_sync`.`t1` WHERE `id` = 12;
SET sql_log_bin = ON;
START REPLICA;
SHOW REPLICA STATUS\G;
"
B. 纯 SQL 模式:
STOP REPLICA;
SET sql_log_bin = OFF;
DELETE FROM `test_sync`.`t1` WHERE `id` = 12;
SET sql_log_bin = ON;
START REPLICA;
SHOW REPLICA STATUS\G;
1.3 应急跳过冲突事务(仅紧急场景)
精准跳过指定 GTID 事务(MySQL 8.0+ 推荐):
A. Docker 执行模式 (包含 -h127.0.0.1):
docker exec -it mysql mysql -uroot -pafe123456 -h127.0.0.1 -e "
STOP REPLICA;
SET GTID_NEXT = '760f0600-f896-11ef-b265-0242ac130002:6'; # 替换为实际冲突 GTID
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START REPLICA;
"
B. 纯 SQL 模式:
STOP REPLICA;
SET GTID_NEXT = '760f0600-f896-11ef-b265-0242ac130002:6';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START REPLICA;
2. 全量备份还原解决冲突(适用于严重冲突场景)
当复制冲突过多、数据不一致严重,或手动修复成本过高时,可以使用全量备份还原的方式彻底解决冲突问题。此方法通过从主库(或备份库)全量备份数据,然后在从库上完全还原,实现数据一致性。
2.1 相关脚本
- 备份脚本:
backup-sync.sh- 在主库或备份库上执行全量备份 - 还原脚本:
restore-sync.sh- 在从库上执行全量还原
2.2 操作流程
步骤 1: 在备份机上执行备份
在需要备份的 MySQL 服务器(通常是主库或数据一致的节点)上执行备份脚本:
# 备份所有数据库(默认)
cd /data/backup/mysql
./backup-sync.sh
# 或指定标签备份
./backup-sync.sh -t conflict_resolve
# 或备份指定数据库
./backup-sync.sh database1 database2
备份脚本会自动:
- 设置 MySQL 为只读模式
- 停止复制(如果是从库)
- 记录当前 GTID 位置
- 执行全量备份并压缩为
.7z文件 - 恢复 MySQL 为读写模式
备份完成后,会在 /data/backup/mysql/ 目录下生成 YYYYMMDDHHMMSS.7z 或 YYYYMMDDHHMMSS_TAG.7z 格式的备份文件。
步骤 2: 传输备份文件到还原机
使用 scp 将备份文件推送到需要还原的 DB 机的 /data/backup/mysql/ 目录:
# 从备份机执行(将备份文件推送到还原机)
scp /data/backup/mysql/YYYYMMDDHHMMSS.7z user@restore-server:/data/backup/mysql/
# 示例
scp /data/backup/mysql/20250127120000.7z root@192.168.1.100:/data/backup/mysql/
注意: 确保还原机的 /data/backup/mysql/ 目录存在且有写入权限。
步骤 3: 在还原机上执行还原
在需要还原的 MySQL 服务器(从库)上执行还原脚本:
cd /data/backup/mysql
# 还原所有数据库
./restore-sync.sh YYYYMMDDHHMMSS.7z
# 或仅还原指定数据库
./restore-sync.sh YYYYMMDDHHMMSS.7z database1.sql
还原脚本会自动:
- 设置 MySQL 为只读模式
- 停止复制
- 重置二进制日志和 GTID
- 导入备份数据(导入时禁用 binlog,避免循环复制)
- 设置 GTID purged(从备份时的 GTID 位置)
- 恢复 MySQL 为读写模式
- 自动启动复制并检查状态
步骤 4: 在备份机上启动同步(重要)
还原完成后,还原脚本会自动启动复制并显示同步状态。确认看到同步成功后,需要在备份机(主库)上执行以下操作:
A. Docker 执行模式 (包含 -h127.0.0.1):
docker exec -it mysql mysql -uroot -pafe123456 -h127.0.0.1 -e "
START REPLICA;
"
B. 纯 SQL 模式:
START REPLICA;
等待 3 秒后,检查同步状态:
A. Docker 执行模式 (包含 -h127.0.0.1):
sleep 3
docker exec -it mysql mysql -uroot -pafe123456 -h127.0.0.1 -e "SHOW REPLICA STATUS\G"
B. 纯 SQL 模式:
-- 等待 3 秒后执行
SHOW REPLICA STATUS\G;
检查关键指标:
Replica_IO_Running: 应为YesReplica_SQL_Running: 应为YesLast_IO_Error: 应为空Last_SQL_Error: 应为空Seconds_Behind_Source: 延迟秒数(应逐渐减小)
2.3 注意事项
- 备份时机: 建议在业务低峰期执行备份,减少对业务的影响
- 网络传输: 确保备份机和还原机之间网络畅通,备份文件较大时传输可能需要较长时间
- 磁盘空间: 确保还原机有足够的磁盘空间存放备份文件和临时解压文件
- 权限要求: 脚本需要 MySQL root 权限,以及
/data/backup/mysql/目录的读写权限 - GTID 一致性: 还原脚本会自动处理 GTID,确保复制能够正常继续
- 备份机同步: 还原完成后务必在备份机(主库)上执行
START REPLICA并检查状态,确保双向复制正常