sql_slave_skip_counter仅对非事务性语句(如myisam的dml)生效,对innodb事务无效;gtid模式下禁用,须用gtid_next注入空事务跳过;跳过后必须核对行数、同步延迟和binlog格式。

sql_slave_skip_counter 跳过的是哪类错误
它只对「非事务性语句」生效,比如 MyISAM 表上的 INSERT、UPDATE、DELETE;对 InnoDB 表的事务性操作基本无效——因为一个事务可能包含多条语句,跳过计数器无法精准定位到出错语句内部。
常见误判场景:
- 看到
Slave_SQL_Running: No和Seconds_Behind_Master: NULL就直接用sql_slave_skip_counter,结果跳过的是空事务或已提交的语句,主从数据进一步错位 - 在 GTID 模式下执行该命令会报错:
ERROR 1794 (HY000): The slave is configured with MASTER_AUTO_POSITION = 1, but the master has sent a non-GTID event - 跳过之后没立刻检查
SHOW SLAVE STATUS\G中的Exec_Master_Log_Pos是否推进,误以为同步已恢复
GTID 模式下不能用 sql_slave_skip_counter,该用什么
GTID 开启后,MySQL 强制要求基于事务 ID 同步,sql_slave_skip_counter 被禁用。必须用 SET GLOBAL gtid_next = 'xxx' 注入空事务来跳过。
实操步骤(需谨慎):
- 先查出出错事务的 GTID:
SHOW SLAVE STATUS\G中找Retrieved_Gtid_Set和Executed_Gtid_Set的差集,或从错误日志里提取类似aaaa-bbbb-cccc-dddd:12345的 ID - 停复制:
STOP SLAVE - 设置跳过目标 GTID:
SET GLOBAL gtid_next = 'aaaa-bbbb-cccc-dddd:12345' - 注入空事务:
BEGIN; COMMIT; - 重置 GTID 模式回自动:
SET GLOBAL gtid_next = 'AUTOMATIC' - 重启复制:
START SLAVE
注意:如果跳错 GTID,后续所有事务都会拒绝执行,只能重搭从库。
跳过之后必须验证的三件事
跳过只是让复制线程跑起来,不代表数据一致。不验证就上线,等于埋雷。
- 核对关键表行数:
SELECT COUNT(*) FROM db1.t1;主从分别执行,数值必须一致(尤其注意带WHERE条件的删改是否漏同步) - 检查
SHOW SLAVE STATUS\G中Seconds_Behind_Master是否持续为 0,且Relay_Log_Space不异常增长 - 确认 binlog 格式是
ROW:SELECT @@binlog_format;—— 若是STATEMENT,跳过可能导致主从数据逻辑不一致(例如含NOW()、UUID()的语句)
为什么跳过不是首选,而应优先查错因
跳过错误本质是绕开问题,不是解决问题。多数线上主从中断,根因在上游:主库被误执行了 DROP TABLE、从库磁盘满导致 relay log 写失败、网络抖动引发半同步超时、甚至主库 max_allowed_packet 设置过小导致大事务截断。
比跳过更值得花时间做的:
- 看从库错误日志:
/var/log/mysql/error.log或SHOW SLAVE STATUS\G中的Last_IO_Error/Last_SQL_Error - 确认主库 binlog 是否完整:
SHOW BINLOG EVENTS IN 'mysql-bin.000123' FROM 123456789 LIMIT 10;查看出错位置附近内容 - 检查从库磁盘空间和权限:
df -h、ls -l /var/lib/mysql/relay-log*
真正难处理的,从来不是“怎么跳过”,而是“为什么这里会出错”——这个点一旦忽略,同一类错误大概率还会在别的位置复现。











