应先查Last_SQL_Error定位错误类型,再按RBR/SBR模式解析真实SQL,跳过仅限单条脏数据场景,GTID下须用SET GTID_NEXT,严重不一致时应重做从库。

先看 Last_SQL_Error 具体报什么错误
看到 Slave_SQL_Running: No,第一反应不是跳过或重启,而是立刻执行 SHOW SLAVE STATUS\G,盯住 Last_SQL_Error 字段。它直接告诉你卡在哪条语句、什么错误码——比如 Error_code: 1062(主键冲突)、Error_code: 1032(找不到记录)、Error_code: 1418(函数不安全)或 Error_code: 1146(表不存在)。这些错误成因完全不同,混用修复方式只会扩大不一致。
-
1062多半是主库插入重复主键,但更常见的是从库残留了不该有的数据(比如人工INSERT过) -
1032表示从库执行UPDATE/DELETE时找不到目标行,可能主库删了、从库没删,也可能表根本没主键 -
1418或1236通常指向binlog_format、函数定义或权限问题,和数据一致性无关,要单独处理 -
1146或"Table 'mysql.xxx' doesn't exist"往往说明系统库版本不一致,比如主库 8.0、从库 5.7
区分 RBR 和 SBR 模式下怎么查真实 SQL
RBR(行复制)模式下,Last_SQL_Error 只显示位置(如 at master log mysql-bin.000012, end_log_pos 123456),看不到具体哪条语句出错。必须用 mysqlbinlog 解析 relay log 才能确认真实操作。
- 先查
Relay_Master_Log_File和Exec_Master_Log_Pos,定位到对应主库 binlog 文件和位置 - 在从库上执行:
mysqlbinlog --base64-output=decode-rows -v /var/lib/mysql/relay-log.000001 | grep -A 10 -B 10 "123456"(把位置替换成实际值) - 如果解析结果里是
Update_rows_v2或Delete_rows_v2,说明是行事件,得结合table_map找到具体表和变更字段 - SBR(语句复制)模式下,
Last_SQL_Error通常直接带出失败的 SQL,但要注意:语句可能依赖临时变量、存储过程或用户自定义函数,在从库不可用
跳过错误前必须确认是否真能跳
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1 或配置 slave_skip_errors 是“让线程动起来”,不是“让数据一致”。跳过只适用于极少数场景,且必须满足前提。
- 仅限单条语句级错误,比如
1062且确认从库多出的那条记录是脏数据(非业务写入) - GTID 模式下不能用
SQL_SLAVE_SKIP_COUNTER,必须用SET GTID_NEXT='xxx'; BEGIN; COMMIT;,否则会破坏 GTID 集合一致性 - 跳过前务必检查
Replicate_Ignore_DB是否误设为mysql——若屏蔽了系统库,后续权限变更永远不同步 - 跳过之后,
Seconds_Behind_Master可能恢复为 0,但SELECT COUNT(*)对比关键表,很可能发现数据已偏差
严重不一致时重做从库最可靠
当 Last_SQL_Error 频繁出现、或报错是 1032 + 大量表缺失/字段不匹配,说明从库数据已严重漂移。此时跳过或手动修复成本远高于重做。
- 主库执行
mysqldump --all-databases --single-transaction --master-data=2 --routines --triggers --events > full_dump.sql,关键参数是--master-data=2 - 从备份文件头提取同步点:
head -n 50 full_dump.sql | grep "CHANGE MASTER TO",拿到MASTER_LOG_FILE和MASTER_LOG_POS - 从库停服务,清空数据目录(或用
DROP DATABASE清掉所有业务库),再导入:mysql - 最后执行
CHANGE MASTER TO MASTER_LOG_FILE='...', MASTER_LOG_POS=...,再START SLAVE
重做从库看似重,但省去了逐条校验、修复、验证的时间。尤其在差异超过 5% 或涉及系统表时,这是唯一能保证最终一致性的路径。


















