pt-table-checksum连不上从库主因是默认用主库账号连从库且依赖processlist查从库线程;Differences=1但pt-table-sync不修复因默认--dry-run;大表慢因CRC计算与chunk划分低效;延迟高时误报因读取旧checksum结果。

pt-table-checksum 连不上从库报错 Cannot connect to slave
根本原因不是网络不通,而是 pt-table-checksum 默认用主库账号去连从库,但很多环境从库只开了复制账号(如 repl@%),没给校验账号权限。它还会默认尝试用 --recursion-method=processlist 去查从库线程,如果从库禁用了 PROCESS 权限或关闭了 performance_schema,就会直接失败。
实操建议:
- 显式指定从库连接参数:
--slave-host=192.168.1.102 --slave-user=checksum_user --slave-password=xxx - 确保该账号在从库有
SELECT+REPLICATION CLIENT权限(REPLICATION CLIENT是为了查SHOW SLAVE STATUS) - 禁用自动发现,强制走 DNS 或指定 IP:
--recursion-method=dsn=h=192.168.1.102,P=3306,u=checksum_user,p=xxx - 别依赖
processlist——主库SHOW PROCESSLIST里看不到从库线程信息,这个方法在跨机房或代理后基本不可靠
校验结果里 Differences 列全是 1,但 pt-table-sync 却不修复
这是因为 pt-table-checksum 只负责“发现差异”,而 pt-table-sync 默认是只打印 SQL,不执行——它默认加了 --dry-run。很多人跑完 checksum 就以为万事大吉,其实 sync 根本没动数据。
实操建议:
- 必须显式加
--execute才会真正同步:pt-table-sync --execute --sync-to-master h=192.168.1.102,u=checksum_user,p=xxx D=test,t=user - 务必先用
--print看生成的 SQL 是否合理,尤其注意 WHERE 条件是否覆盖全表、有没有触发主键冲突 - 避免在业务高峰跑
--execute:它会按 chunk 分批 DELETE + REPLACE,锁表时间虽短,但高并发下可能堆积成锁等待 - 如果从库有唯一键冲突(比如主库 INSERT 后又删了,从库还留着),
pt-table-sync会跳过该 chunk 并报错DBD::mysql::st execute failed: Duplicate entry,得人工介入
为什么 pt-table-checksum 在大表上跑得慢甚至卡住
核心瓶颈不在网络,而在 MySQL 自身:它默认对每张表做 CRC32(CONCAT(...)),字段越多、值越长、NULL 越多,计算越慢;更关键的是,它依赖 SELECT ... INTO OUTFILE 或临时表分 chunk,如果表没主键或主键不是整型,chunk 划分会退化成全表扫描。
实操建议:
- 确认表有合适主键:最好是单调递增的
BIGINT,避免用 UUID 或复合主键 - 用
--chunk-index指定高效索引,比如时间字段:--chunk-index=created_at(前提是该字段有索引且分布均匀) - 调低
--chunk-size(默认 1000 行)可减少单次查询压力,但会增加总耗时和校验延迟;一般 500–2000 之间按表大小权衡 - 避开
--algorithm=STREAM:虽然能减少内存占用,但在从库 IO 压力大时容易触发Lost connection to MySQL server
从库延迟高时运行 pt-table-checksum 导致误报
这是最隐蔽的问题:pt-table-checksum 在主库写 checksum 结果到 percona.checksums 表,然后立刻去从库查这张表——如果从库延迟 30 秒,它读到的就是 30 秒前的旧值,自然显示 Differences=1,但其实只是延迟,不是不一致。
实操建议:
- 跑之前先看
Seconds_Behind_Master,超过 5 秒就暂停,等追平再校验 - 加
--replicate-check-only参数,它会跳过写主库 checksum,只读从库已有的结果(适合周期性复查) - 不要把
percona.checksums表放在系统库mysql下——某些备份工具或权限策略会过滤掉它,导致从库查不到表 - 如果必须在延迟状态下校验,至少加
--max-lag=1s,让工具自动检测并暂停,而不是硬扛
真正难的不是跑通命令,是区分「数据真不一致」和「只是复制慢了一拍」——后者占线上问题的七成以上,但日志里都显示 Differences=1。


















