应优先用 STOP REPLICA SKIP COUNTER = 1(MySQL 8.0.26+),RBR模式下需设 slave_exec_mode = 'IDEMPOTENT';跳过仅治标,须查清主键冲突根源并校验数据一致性。

主键冲突让复制停在 ERROR 1062,怎么跳过?
直接跳过不是不行,但 Slave_skip_errors 是个全局开关,一旦启用,所有错误类型都可能被忽略,包括真正要命的 ERROR 1032(行不存在)或 ERROR 1053(服务器关闭),不是只管主键冲突。它不区分语句来源、不校验数据一致性,跳过之后从库数据就和主库对不上了。
实操建议:
-
Slave_skip_errors只应在紧急恢复时临时用,用完立刻关掉,不能写进配置文件长期开启 - 跳过前先查
SHOW SLAVE STATUS\G,确认Last_SQL_Error确实是Duplicate entry 'xxx' for key 'PRIMARY' - 跳过命令是
SET GLOBAL sql_slave_skip_counter = 1;,不是改配置再重启——后者要重启 IO/SQL 线程,容易丢事件 - MySQL 8.0.26+ 支持
STOP REPLICA SKIP COUNTER = 1;,更安全,推荐优先用
为什么 sql_slave_skip_counter 有时不生效?
因为它只对基于语句复制(SBR)有效,而 MySQL 5.7.7+ 默认用的是基于行复制(RBR)。在 RBR 下,sql_slave_skip_counter 被忽略,跳不过去。
实操建议:
- 先看
SHOW SLAVE STATUS\G里的Replicate_Rewrite_DB和Exec_Master_Log_Pos,再结合SELECT @@binlog_format;确认复制格式 - RBR 场景下,必须用
SET GLOBAL slave_exec_mode = 'IDEMPOTENT';,它允许重复插入时忽略主键冲突(仅限INSERT类操作) -
IDEMPOTENT模式有副作用:它也会让UPDATE找不到行时不报错,相当于静默失败,监控上容易漏掉 - 别混淆
slave_exec_mode和sql_slave_skip_counter——前者是行为模式,后者是计数器,机制完全不同
想精准跳过某条冲突 SQL,而不是整个事件?
不能。MySQL 复制的最小执行单位是「事件(event)」,不是单条 SQL。一个 INSERT ... SELECT 或批量 INSERT 会被打包成一个事件,sql_slave_skip_counter = 1 跳过的是一整个事件,里面可能含多条语句。
实操建议:
- 如果主库误执行了不该有的
INSERT,最稳妥的方式是:在从库手动DELETE冲突行,再START SLAVE; - 用
mysqlbinlog解析主库 binlog,定位到出问题的 event 位置(at xxx),然后用CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='xxx', SOURCE_LOG_POS=yyy;跳到下一条 - 注意:
SOURCE_LOG_POS必须指向下一个 event 的开头,不是当前 event 的末尾,算错会导致复制错位或重复执行 - 跳 position 是高危操作,务必先在测试库验证 binlog 解析结果
用 pt-slave-restart 自动跳过靠谱吗?
它只是封装了 sql_slave_skip_counter 和状态轮询,能自动检测并跳过指定错误码(比如 --error-numbers=1062),但没解决根本问题:跳过之后数据不一致依然存在。
实操建议:
- 适合临时救急,比如半夜报警、只差几条数据且业务可接受短暂不一致
- 它默认每秒检查一次复制状态,频繁跳过会掩盖真实问题,比如主从写入逻辑不同步、应用双写未关等
- 不要用它替代数据校验,跳过之后必须跑
pt-table-checksum对比主从表级一致性 - 它对 GTID 复制支持有限,开启 GTID 后需配合
--recursion-method=none和手动SET GTID_NEXT,复杂度陡增
真正难的不是跳过,而是确认这条冲突数据本就不该存在——是主库误操作?从库残留脏数据?还是应用层没做幂等?这些不会因为跳过就消失。










