必须立刻看slave_io_running、slave_sql_running、last_sql_error三个字段:任一为no即复制中断,last_sql_error中duplicate entry或can't find record表明数据不一致。

SHOW SLAVE STATUS\G 里哪些字段必须立刻看
复制是否还在跑、卡在哪一步,全靠这三个字段定性:Slave_IO_Running、Slave_SQL_Running、Last_SQL_Error。只要任一为 No,说明复制已中断;Last_SQL_Error 里出现 Duplicate entry 或 Can't find record,基本就是数据不一致的直接证据。
别只盯着 Seconds_Behind_Master——它为 0 不代表数据一致,可能 SQL 线程已停但没报错;它持续增长也不一定就是慢,可能是主库刚执行了大事务,而从库还在回放中间状态。
额外注意两个位置值:Read_Master_Log_Pos 和 Exec_Master_Log_Pos。如果两者差距拉得越来越大,说明 IO 线程在拉日志,但 SQL 线程根本没来得及执行,问题出在从库执行层(比如锁冲突、索引缺失、慢查询)。
pt-table-checksum 怎么用才不翻车
这个工具不是“一键校验”,而是依赖主从之间能正常通信、表结构完全一致、字符集相同、且从库开启了 log_slave_updates。漏掉任意一点,checksum 就会漏比或误报。
执行前必须确认:
-
pt-table-checksum必须在主库运行,它会自动把校验结果写入从库的percona.checksums表 - 主从
max_allowed_packet值要一致,否则大表校验时会因包大小限制失败 - 避免在业务高峰期跑,它会对表加
FOR UPDATE锁(虽是行级,但高并发下仍可能阻塞写入) - 首次运行建议加
--no-check-binlog-format,防止因 binlog_format=STATEMENT 导致 checksum 不可重复
校验完查从库:SELECT * FROM percona.checksums WHERE this_crc != master_crc OR is_drift = 1; —— 只有这两列同时满足,才算真实不一致。
为什么不能直接用 SET GLOBAL sql_slave_skip_counter = 1
这个命令只适合跳过一条“明确无害”的事件,比如主库执行了 CREATE TABLE IF NOT EXISTS,但从库已存在同名表导致报错。但它完全不管数据逻辑,跳过的可能是关键更新或删除。
更危险的是 GTID 模式下禁用此命令:MySQL 会拒绝执行,并报错 Cannot use sql_slave_skip_counter when @@GLOBAL.GTID_MODE = ON。强行绕过(比如先关 GTID)会导致后续复制无法定位事务,整个复制链断裂。
真正安全的跳过方式是:
- 记下
Retrieved_Gtid_Set和Executed_Gtid_Set - 执行
SET GTID_NEXT = 'xxx-xxx-xxx:nnn'; BEGIN; COMMIT;(空事务) - 再
SET GTID_NEXT = 'AUTOMATIC'; START SLAVE;
本质是伪造一个已执行的 GTID,让复制器认为该事务已完成,而不是跳过它。
什么时候该放弃修复、直接重做从库
当 pt-table-sync --print 输出的修复语句超过几万行,或单表差异行数 > 总行数 5%,就别硬修了。在线修复耗时长、压力大,还可能因网络中断或权限不足中途失败,留下半修复状态。
重做从库的关键动作只有三步:
- 主库用
mysqldump --single-transaction --master-data=2备份(务必带--master-data=2) - 从备份文件头提取
CHANGE MASTER TO MASTER_LOG_FILE='...', MASTER_LOG_POS=...信息 - 从库清空后导入,并用上面提取的位置点重新
CHANGE MASTER TO
容易被忽略的是:重做前必须停写入,否则备份时刻之后的新数据会丢失;重做后别急着上线,先用 SELECT COUNT(*) 和 MD5(GROUP_CONCAT(...)) 抽样比对几个核心表,确认一致性再切流量。











