SET GLOBAL sql_slave_skip_counter = 1 仅对 SBR(STATEMENT)且未启用 GTID 的复制有效;GTID 模式下会报错,须改用 SET GTID_NEXT + 空事务方式跳过。

为什么 SET GLOBAL sql_slave_skip_counter = 1 有时不生效
这个命令只对基于 binlog_format=STATEMENT 的复制有效,且要求未启用 GTID。如果 MySQL 启用了 GTID(gtid_mode=ON),执行 SET GLOBAL sql_slave_skip_counter = 1 会直接报错:ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. 此时跳过事务必须改用 GTID_NEXT 方式注入空事务。
在 GTID 模式下跳过单条错误事务的正确步骤
先确认从库是否启用了 GTID:
SELECT @@gtid_mode, @@enforce_gtid_consistency;
若返回 ON,则按以下顺序操作:
STOP SLAVE;- 查出当前报错事务的 GTID:
SHOW SLAVE STATUS\G中看Retrieved_Gtid_Set和Executed_Gtid_Set,再结合Last_SQL_Error定位出错位置 - 手动设置下一个要执行的 GTID(需与出错事务一致):
SET GTID_NEXT = 'e46c9961-5780-11ea-bf2f-000c128a8b6b:12345';(值来自Last_IO_Error或Relay_Master_Log_File+Exec_Master_Log_Pos对应的 binlog event) - 执行空事务:
BEGIN; COMMIT; - 重置 GTID_NEXT 回自动模式:
SET GTID_NEXT = 'AUTOMATIC'; START SLAVE;
跳过前必须检查的三个关键点
盲目执行 sql_slave_skip_counter 或空事务,可能让主从数据永久不一致。动手前务必确认:
- 错误类型是否真的可跳过:如
Error_code: 1032(记录不存在)或Error_code: 1062(主键冲突)通常可跳,但Error_code: 1054(字段不存在)说明表结构不一致,必须先修复结构 - 主库该事务是否已真正提交:若主库因崩溃未刷盘,而从库已拉到半截 binlog,跳过会导致从库多出脏数据
- 是否启用了多线程复制(
slave_parallel_workers > 0):此时sql_slave_skip_counter行为不可靠,建议先设为 0 再操作
跳过之后验证同步是否真恢复正常
执行 START SLAVE 后不能只看 Slave_IO_Running 和 Slave_SQL_Running 都是 Yes 就算完事。重点检查:
-
Seconds_Behind_Master是否持续下降而非卡死 -
Exec_Master_Log_Pos是否在推进,且与主库show master status的Position差距不再扩大 - 手动在主库执行一条带明显特征的 INSERT,比如
INSERT INTO test_sync VALUES (UNIX_TIMESTAMP(), 'verify');,然后立刻去从库查是否同步过来
跳过的本质是“绕开问题”,不是“解决问题”。只要表结构、初始化数据、GTID 配置、binlog 格式这四者中任一环没对齐,跳过操作就只是把故障延后爆发而已。


















