pt-table-checksum必须在主库执行,依赖statement格式binlog和主库写权限,通过生成校验sql并由从库重放比对crc值;若binlog为row/mixed需加--no-check-binlog-format(不推荐),校验结果存于percona.checksums表,查该表才能确认不一致。

pt-table-checksum 必须在主库执行,不能在从库运行
因为 pt-table-checksum 依赖主库的 binlog 格式(必须为 STATEMENT)和写权限,它通过在主库生成校验 SQL 并让从库重放来比对结果。如果误在从库执行,会报错 Cannot checksum tables on a slave unless --replicate is specified and --no-check-binlog-format is used,且校验逻辑完全失效。
确认方式:执行 SELECT @@binlog_format;,输出必须是 STATEMENT;若为 ROW 或 MIXED,需临时修改(注意业务影响)或加 --no-check-binlog-format 强制跳过检查(不推荐生产环境跳过)。
核心参数组合决定是否能发现主从不一致
仅运行 pt-table-checksum 默认不会主动报告不一致——它只把校验结果写入指定表(如 percona.checksums),是否“发现”取决于后续如何查这个表。常见漏掉的关键点:
-
--replicate=percona.checksums:必须指定,否则校验结果不落地,无法比对 -
--no-check-plan:避免因 MySQL 执行计划变化导致误判(尤其大表) -
--chunk-size-limit=2.0:防止单 chunk 过大卡住复制,建议设为 1.5~2.0 -
--recursion-method=processlist或hosts:确保自动发现从库,否则只校验主库本地
执行后,校验数据会写入 percona.checksums 表,其中 diffs 列为 1 即表示该 chunk 主从不一致。
怎么快速确认主从是否真有不一致
别等脚本输出“Diffs found”,直接查 percona.checksums 表最可靠:
SELECT db, tbl, SUM(this_crc != master_crc OR ISNULL(master_crc) OR ISNULL(this_crc)) AS diff_cnt FROM percona.checksums WHERE (master_crc != this_crc OR master_crc IS NULL OR this_crc IS NULL) GROUP BY db, tbl;
注意:master_crc 是主库算出的 CRC,this_crc 是从库回放后算出的值。只要任一 chunk 的这两个值不等,就说明该 chunk 范围内存在行级差异。
常见干扰项:
- 从库延迟高时,
this_crc可能还是旧值,需等 SQL 线程追平再查 - 从库设置了
replicate_ignore_db或过滤规则,会导致对应表不写checksums表,查不到记录 ≠ 一致 -
pt-table-checksum默认跳过mysql、information_schema等系统库,不要指望它覆盖全部
校验后必须用 pt-table-sync 修复,但操作极敏感
pt-table-sync 不是“一键修复”,它是基于 pt-table-checksum 的结果生成修复 SQL,默认只打印不执行。真正风险在于:
- 必须在从库上运行(不是主库!),且连接的是从库实例
-
--sync-to-master模式下,会以主库为基准改从库,但若主库本身已损坏,会把错误同步过去 - 无事务包装,单条
REPLACE或DELETE/INSERT执行失败即中断,需人工介入 - 大表修复可能锁表或拖慢复制,务必避开业务高峰,并监控
Seconds_Behind_Master
安全做法:先加 --print 看生成的 SQL 是否合理,再加 --execute;修复前务必备份从库对应表。
真正容易被忽略的是:校验过程本身会产生大量 binlog,如果主库磁盘空间紧张或从库 IO 已饱和,校验还没完,复制就可能断裂。跑之前先看 df -h 和 iostat -x 1。











