必须在主库执行,有效性须查从库percona.checksums表中this_crc != master_crc的记录;直连从库会跳过复制链路,导致单点校验失效,且因权限/配置不匹配易报错或卡住。

必须在主库执行,且结果有效性不看命令行输出的 Diffs = 0,而要看从库 percona.checksums 表中 this_crc != master_crc 的记录。
为什么不能在从库上直接运行 pt-table-checksum
工具设计上就要求校验语句必须走复制链路:它在主库生成类似 REPLACE INTO percona.checksums SELECT db, tbl, chunk, CRC32(CONCAT(...)), COUNT(*) FROM ... WHERE id BETWEEN ? AND ? 的语句,这些语句需写入 binlog,并由从库 SQL 线程重放——重放过程会触发从库用自己的数据重新计算 this_crc,才能和主库写的 master_crc 对比。
若加 --host=从库IP 强行直连从库:
- 工具会尝试在从库执行
SHOW PROCESSLIST、修改binlog_format等操作,但只读从库通常禁用SUPER权限,直接卡在Waiting for replica mysql2 - 即使连上,也跳过复制逻辑,变成单点校验,完全失去“主从一致性”意义
- 常见报错如
Cannot connect to host或Access denied,本质是权限/配置不匹配,不是网络问题
执行前必须确认的三件事(缺一不可)
否则工具启动即失败,或输出 0 differences 却实际漏检:
-
SHOW SLAVE STATUS\G中Slave_IO_Running = Yes、Slave_SQL_Running = Yes,且Seconds_Behind_Master≤ 1 秒 - 主库已显式配置
report_host和report_port(SHOW SLAVE HOSTS已废弃,不能依赖) - 校验账号(如
chkuser)已在每个从库执行授权:GRANT SELECT, REPLICATION CLIENT ON *.* TO 'chkuser'@'%';MySQL 8.0+ 还需确认认证插件兼容(老版本pt-table-checksum 3.1.x不支持caching_sha2_password)
--no-check-binlog-format 和 --replicate 怎么设才不踩坑
默认参数在生产环境基本不可用,尤其大表场景:
-
--no-check-binlog-format:必须加。MySQL 5.7.7+ 默认binlog_format = ROW,而pt-table-checksum实际依赖 ROW 模式下语句可重放;不加会直接退出 -
--replicate=percona.checksums:指定校验结果写入位置,必须确保该库表存在且可写;首次运行务必加--create-replicate-table -
--chunk-size=1000:默认按主键范围分片,1000 行/块较稳妥;过大易锁表或超时,过小则 IO 频繁、校验慢 -
--nocheck-replication-filters:必须加,否则遇到replicate_ignore_db=percona会导致从库压根不同步percona.checksums表,查出来永远空 -
--max-lag=1:从库延迟超过 1 秒就暂停,防止校验结果反映“历史状态”而非当前一致
怎么看结果才算真正一致?别信命令行输出
命令行末尾显示 Diffs = 0 完全不可信——它只是告诉你“没往 percona.checksums 写差异记录”,不代表数据真一致。
必须登录每个从库,手动执行:
SELECT * FROM percona.checksums WHERE this_crc != master_crc OR is_bad = 1;
只有该查询返回空结果,才说明当前时刻主从数据块级一致。最容易被忽略的是:这个检查必须在所有从库上分别执行,不能只查一个;另外,如果从库曾跳过复制事件(如 SET GLOBAL SQL_SLAVE_SKIP_COUNTER),或使用了临时表、含 LIMIT 无 ORDER BY 的 DML,master_crc 和 this_crc 天然就不等——这种不一致是复制机制本身导致的,不是工具误报。











