ERROR 1062主从复制中断应精准跳过事务而非硬跳:GTID模式下用SET GTID_NEXT+BEGIN/COMMIT跳过;非GTID模式需通过relay_log_pos定位并CHANGE MASTER TO下一事务起点;禁用sql_slave_skip_counter,避免数据错乱。

遇到 ERROR 1062:主从复制因唯一键冲突中断,直接跳过不安全
MySQL 复制报错 1062(Duplicate entry)本质是:从库执行主库发来的写操作时,发现某条记录已存在(比如 INSERT INTO users VALUES (1, 'a'),但 ID=1 的行已在从库存在),触发唯一约束失败。此时复制线程停止,Seconds_Behind_Master 变为 NULL。
常见诱因包括:INSERT ... ON DUPLICATE KEY UPDATE 在主库成功、但从库因数据不一致被当成纯 INSERT 执行;人为在从库误写入;或主库 binlog 格式为 STATEMENT 且语句非确定性。
- 别用
SET GLOBAL sql_slave_skip_counter = 1硬跳过——它只对基于语句的复制(SBR)有效,且跳过的不是“错误那条”,而是“下一条事件”,极易引发后续数据错乱 - 若用的是
ROW格式(推荐且默认),这个命令根本不起作用,还会报错ERROR 1374 (HY000): This operation cannot be performed with a running slave SQL thread - 真正要跳过,得先停 SQL 线程,再用
gtid_next或relay_log_pos定位并跳过具体事务
用 GTID 跳过单个事务(推荐,适用于 gtid_mode=ON)
GTID 模式下每个事务有唯一标识,跳过精准、可审计。前提是主从都开启 GTID,且从库处于 SQL_THREAD_STOPPED 状态。
- 查当前错误事务 GTID:
SHOW SLAVE STATUS\G,找Retrieved_Gtid_Set和Executed_Gtid_Set,对比差值;或看Replicate_Ignore_Server_Ids是否为空 - 确认出错事务的 GTID(例如
3e11fa47-71ca-11e1-9e33-c80aa9429562:23),然后执行:STOP SLAVE;<br>SET GTID_NEXT='3e11fa47-71ca-11e1-9e33-c80aa9429562:23';<br>BEGIN; COMMIT;<br>SET GTID_NEXT='AUTOMATIC';<br>START SLAVE;
- 注意:
GTID_NEXT必须严格匹配报错事务的 GTID,大小写、冒号、分号都不能错;执行BEGIN; COMMIT;是为了“占位”消耗掉这个 GTID,否则启动复制会重试原事务
用 relay_log_file + relay_log_pos 跳过(兼容所有模式,但需手动定位)
当没开 GTID,或你不确定 GTID 状态时,靠中继日志位置跳过最稳妥。关键不是“跳多少”,而是“跳到哪”——必须跳到出错事务的下一条事务开头。
- 先停复制:
STOP SLAVE; - 查错误位置:
SHOW SLAVE STATUS\G,记下Relay_Master_Log_File和Exec_Master_Log_Pos(这是主库 binlog 中该事务的结束位置) - 登录主库,用
mysqlbinlog解析对应 binlog 文件:mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000001 | grep -A 10 -B 10 "your_duplicate_value",找到出错事务的end_log_pos,再找下一个GTID_LOG_EVENT或QUERY_EVENT的起始位置 - 设新起点:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=1234567;,其中1234567是下一个事务的开始位置 - 重启:
START SLAVE;
为什么不能无脑清空从库重搭?
重搭看似一劳永逸,但实际代价常被低估:大表 mysqldump 导出导入期间主库持续写入,从库恢复后可能立刻又因延迟追不上而断;xtrabackup 虽快,但备份+传输+准备+应用日志仍需时间,期间主库故障风险未消除。
- 线上从库延迟超过 1 小时,重搭过程中新延迟可能滚雪球到数小时
-
RESET SLAVE ALL后忘记重设MASTER_AUTO_POSITION=1(GTID 模式)或MASTER_LOG_FILE(传统模式),会导致复制无法启动 - 最隐蔽的坑:主库 binlog 过期(
expire_logs_days设置过小),重搭时需要的日志已被自动清理,只能停主库补日志或接受数据丢失
真正省事的方式,是日常就做好主从数据一致性校验(比如用 pt-table-checksum),把问题卡在刚冒头的时候。等看到 1062,说明不一致已经发生,跳过只是止损,不是修复。











