sql_slave_skip_counter仅在SBR模式、GTID关闭、SQL线程执行出错(如1062/1032)时有效;需STOP SLAVE后设GLOBAL值再START SLAVE,且必须确认错误可安全跳过,否则易致数据不一致。

sql_slave_skip_counter 在什么场景下才该用
它只对基于语句复制(SBR)且错误发生在 SQL 线程执行阶段时有效,比如主从数据不一致导致 Duplicate entry 或 No such row 这类“重放失败”错误。如果是 I/O 线程出错(如网络中断、Got fatal error 1236)、GTID 模式开启、或使用了基于行复制(RBR),sql_slave_skip_counter 直接无效,强行设会静默忽略或报错。
跳过前必须确认的三件事
sql_slave_skip_counter 是“跳过下 N 条事件”,不是“跳过当前错误那条”。实际生效依赖于 binlog 中事件的组织方式——一个事务可能包含多个事件,而它只按 event 计数,不是按语句或事务计数。容易误判的根本原因就在这儿。
- 先执行
SHOW SLAVE STATUS\G,确认Seconds_Behind_Master非 NULL、Slave_SQL_Running_State显示 “Reading event from the relay log” 或类似卡在 SQL 线程,且Exec_Master_Log_Pos和Relay_Log_Pos停滞 - 检查
Relay_Master_Log_File和Exec_Master_Log_Pos对应的主库 binlog 文件和位置,用mysqlbinlog解析确认出错的那条语句是否真的可安全跳过(比如是不是一条INSERT IGNORE被误写成INSERT) - 确保没开启 GTID:如果
gtid_mode = ON,sql_slave_skip_counter被禁用,此时必须用SET GTID_NEXT='xxx'; BEGIN; COMMIT;方式注入空事务来跳过
实际跳过的操作步骤和典型错误
跳过动作本身只有两步,但顺序和上下文错一点就会白干:
- 先停复制:
STOP SLAVE; - 再设计数器:
SET GLOBAL sql_slave_skip_counter = 1;(注意是GLOBAL,且值为整数,不能是表达式) - 最后启动:
START SLAVE;
常见翻车点:START SLAVE 后立刻查状态,发现还是 Slave_SQL_Running: No——大概率是因为跳过的那条事件之后,下一条又出错了;或者你跳的是事务中间某个 event,导致后续事件因缺失上下文继续失败。这时不能连跳 2 次,得回到上一步重新分析 binlog 结构。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
比跳过更稳妥的替代方案
线上环境优先考虑修复数据一致性,而不是跳过。比如遇到 Duplicate entry '123' for key 'PRIMARY',可以登录从库手动 DELETE FROM tbl WHERE id = 123;,再 START SLAVE;。这样既不破坏 GTID,也不依赖事件计数逻辑,还能避免因跳过引发的后续主键冲突扩散。只有当错误语句明确无副作用(比如一条日志表 INSERT 因磁盘满失败),且无法快速修复主从数据时,才把 sql_slave_skip_counter 当临时止血手段。
真正难的从来不是设那个数字,而是判断“这条语句到底能不能跳”——这需要看懂 binlog 事件流、理解事务边界、并清楚业务语义。没做这层分析就执行 SET GLOBAL sql_slave_skip_counter,等于蒙眼开车。










