sql_slave_skip_counter不是首选方案,因其在GTID模式下直接失效,仅适用于binlog_format=STATEMENT且gtid_mode=OFF的旧环境;GTID模式下应使用SET GTID_NEXT+空事务方式跳过1062错误。

为什么 sql_slave_skip_counter 不是首选方案
这个变量本质是让从库跳过下一条事件,但 MySQL 5.7+ 默认用 GTID 复制后,sql_slave_skip_counter 直接失效——它只在 binlog_format=STATEMENT 且 gtid_mode=OFF 时才起作用。强行设它会报错 ERROR 1794 (HY000): The value of @@sql_slave_skip_counter is ignored because the server is running with --gtid-mode=ON。如果你看到 1062 错误(主键/唯一键冲突),大概率已经启用了 GTID。
1062 报错时真正该检查的三件事
1062 是从库执行 INSERT 或 REPLACE 时发现主键或唯一索引已存在。这不是“数据不同步”那么简单,而是“主从对同一逻辑操作产生了不同结果”。常见诱因包括:
- 从库被误写:比如应用直连了从库做 INSERT,后续主库也发来同主键记录
- 主库上用了
INSERT IGNORE或REPLACE INTO,但从库没走相同逻辑(尤其跨版本或参数不一致时) - 主库 binlog 中记录的是 ROW 格式,但某条 UPDATE 实际影响了多行,而从库触发器/外键/约束导致行为偏移
GTID 模式下跳过 1062 的正确姿势
必须用 SET GTID_NEXT + 空事务方式“伪造”一个已执行过的 GTID,让从库跳过当前卡住的事务。步骤严格如下:
- 先查卡住位置:
SHOW SLAVE STATUS\G,记下Retrieved_Gtid_Set和Executed_Gtid_Set - 停复制:
STOP SLAVE - 设下一个要跳过的 GTID:
SET GTID_NEXT='xxx:yyy'(其中xxx:yyy必须是Retrieved_Gtid_Set里存在、但不在Executed_Gtid_Set里的那个 GTID) - 执行空事务:
BEGIN; COMMIT; - 重置 GTID_NEXT:
SET GTID_NEXT='AUTOMATIC' - 重启复制:
START SLAVE
漏掉任何一步都可能让复制永久断裂。特别是 GTID_NEXT 值抄错、或 COMMIT 前断开连接,会导致从库状态不可逆错乱。
比跳过更值得做的两件事
1062 往往是表层症状。比起每次手动跳过,优先确认:
- 所有从库是否设置了
read_only=ON(且没被绕过)——这是防误写的底线 - 主库 binlog 是否启用了
log_slave_updates?如果没开,级联复制场景下中间从库无法正确生成 GTID,也会引发 1062 类似表现
跳过只是临时止血,真正稳定的同步依赖于写入路径的隔离和 binlog 行为的一致性。一旦发现 1062 频繁出现,说明应用层或部署层有未被识别的写入泄漏,这时候查 SQL 审计日志比调参数更重要。


















