必须先执行show variables like 'gtid_mode'确认是否为on,gtid模式下sql_slave_skip_counter已弃用,须用stop replica→set gtid_next→begin;commit→set gtid_next='automatic'→start replica五步注入空事务跳过,漏一步或抄错gtid将导致复制永久中断。

先确认是不是 GTID 模式,否则跳过命令直接报错
执行 SHOW VARIABLES LIKE 'gtid_mode';,返回 ON 就是 GTID 模式。这时候 SET GLOBAL sql_slave_skip_counter = 1 会立刻报错 ERROR 1251 或 ERROR 1858,不是你输错了,是 MySQL 8.0.23+ 默认启用 GTID 后这个变量已被弃用。
常见误判:看到 Executed_Gtid_Set 非空就以为开了 GTID —— 实际可能是旧从库残留值,必须以 gtid_mode 变量为准。主库开 GTID、从库没开,也会导致复制卡在 1062 且无法跳过。
GTID 模式下跳过 1062 的唯一合法操作路径
跳过本质是“伪造已执行”,靠注入空事务消耗掉冲突事务的 GTID。漏一步或抄错一位字符,从库 GTID 状态就永久错乱,只能重建。
- 查出错事务 GTID:运行
SHOW SLAVE STATUS\G,从Last_SQL_Error字段提取完整 GTID,形如3e11fa47-71ca-11e1-9e33-c80aa9429562:23,冒号前后不能有空格,大小写必须完全一致 - 停 SQL 线程:
STOP REPLICA;(MySQL 8.0.22+ 推荐用REPLICA,SLAVE已弃用) - 注入空事务:
SET GTID_NEXT = '3e11fa47-71ca-11e1-9e33-c80aa9429562:23';→BEGIN;→COMMIT; - 重置并重启:
SET GTID_NEXT = 'AUTOMATIC';→START REPLICA;
注意:BEGIN; COMMIT; 必须是空事务,不能带任何 DML;如果连接在 COMMIT 前断开,GTID 集合将不完整,复制无法恢复。
非 GTID 模式(binlog position)下怎么安全跳过
传统模式下 sql_slave_skip_counter 仅对 binlog_format = STATEMENT 稳定有效;ROW 格式下执行会报 ERROR 1374,且该命令跳的是“下一条事件”,不是当前错误那条,极易引发后续数据错位。
更稳妥的做法:
- 先停 SQL 线程:
STOP SLAVE SQL_THREAD; - 定位中继日志位置:从
SHOW SLAVE STATUS\G中取Relay_Master_Log_File和Exec_Master_Log_Pos - 用
mysqlbinlog解析对应 binlog 文件,确认冲突 SQL 内容,再决定是删从库脏数据,还是手动执行修复语句 - 避免配置
slave-skip-errors = 1062—— 它需重启 MySQL,线上不可行,还会掩盖所有 1062,让不一致静默扩大
跳过只是临时止血,真正要盯紧的是写入源头
1062 不是孤立错误,而是主从数据已不一致的明确信号。跳过一次,下次大概率在别的表、别的字段上再爆一次。
必须立即排查:
- 检查
SELECT @@read_only;和SELECT @@super_read_only;,确认从库是否真被设为只读;查 general_log 或审计日志,看是否有绕过应用层直接写入从库的 DML - 确认应用是否双写(比如 ORM fallback 到从库执行 INSERT)
- 检查主库 binlog 是否有非幂等语句(如未加 WHERE 的 UPDATE、无 LIMIT 的 DELETE)
最危险的操作是“跳过完就不管了”。只要没定位到那条重复插入语句是从哪来的,问题就会反复出现,且越积越多。











