pt-table-checksum是主从切换前必须执行、切换后必须立即验证的一致性确认手段,仅检测不修复;修复需用pt-table-sync,但风险极高须人工审慎执行。

pt-table-checksum 不是主从切换后的“补救工具”,而是切换前必须跑、切换后必须立刻验证的“确认手段”。它本身不解决一致性,只告诉你:现在到底一不一致。真要修复,得靠 pt-table-sync,但那步风险极高,不能盲目执行。
为什么主从切换后必须立刻校验?
切换(failover)过程里最容易出问题的环节不是复制断开,而是“你以为切完了,其实某些事务没同步完”。比如:
- 新主库上刚提交的事务还没来得及刷 binlog 或传到从库
- 旧主库残留连接还在写入(read_only=OFF 未生效或被绕过)
- GTID 模式下
gtid_executed和gtid_purged不对齐,导致部分从库跳过关键事务
这些情况不会报错,但数据已经分叉。pt-table-checksum 是唯一能在线、低干扰、定位到具体 chunk 的手段。
切换后校验前必须检查的三件事
很多校验失败或结果不准,根本不是工具问题,而是环境没理清:
-
SHOW SLAVE STATUS\G在所有从库上执行,确认Seconds_Behind_Master是0,且Slave_IO_Running和Slave_SQL_Running都为Yes - 主库(现主库)的
report_host和report_port必须显式配置(不能依赖默认值),否则pt-table-checksum会按空或错的地址连从库 - 从库必须允许远程连接:
bind_address不能是127.0.0.1;校验用户在从库上要有REPLICATION CLIENT+SELECT权限(不只是主库有)
校验命令怎么写才不踩坑?
切换后第一轮校验,建议用最保守、最明确的参数组合,避免自动发现逻辑引入不确定性:
- 强制指定从库发现方式:
--recursion-method=dsn=D=percona,t=dsns,并提前在主库建好percona.dsns表,填入每个从库的h=ip,P=port,u=user,p=pass - 禁用 binlog 格式检查:
--no-check-binlog-format(ROW 模式下必须加) - 显式指定校验表位置:
--replicate=percona.checksums,且确保该表在所有从库上存在、可写 - 加延迟容忍上限:
--max-lag=1,超过 1 秒自动暂停,防止校验时从库越追越远
示例命令:
pt-table-checksum \ --host=192.168.10.100 \ --user=chkuser \ --password='xxx' \ --databases=myapp \ --replicate=percona.checksums \ --no-check-binlog-format \ --recursion-method=dsn=D=percona,t=dsns \ --max-lag=1 \ --chunk-time=0.3
看到 DIFFS=1 怎么办?别急着 sync
DIFFS=1 只表示 checksum 值不同,不等于数据行内容一定错——可能只是校验期间从库刚好卡了一下,或者某 chunk 被跳过导致对比基准偏移。
- 先查
percona.checksums表:SELECT * FROM percona.checksums WHERE this_crc != master_crc OR ISNULL(master_crc) != ISNULL(this_crc); - 重点看
chunk和lower_boundary/upper_boundary,定位到具体主键范围 - 手动比对一行:
SELECT * FROM myapp.orders WHERE id BETWEEN 10000 AND 10050 ORDER BY id;主从各跑一次,肉眼扫差异 - 确认是真实不一致后,再用
pt-table-sync --print生成 SQL,人工 review 后决定是否--execute
真正危险的是:把 --sync-to-master 误写成 --slave,结果让从库当源,反向覆盖新主库——这种操作不可逆。











