pt-table-checksum 必须连通主库才能运行,否则直接报错退出;校验结果需查从库 percona.checksums 表比对 master_crc 与 this_crc;大表需调小 --chunk-size 并确保索引有效;从库复制过滤规则可能使 checksum 失效。

pt-table-checksum 连不上主库就别往下试了
连不上主库时,pt-table-checksum 会直接报错退出,比如 DBI connect failed: Access denied for user 或 Can't connect to MySQL server。它不会自动 fallback 到从库,也不会跳过校验——没主库连接,整个流程就卡死。
确保用的账号有:REPLICATION CLIENT、PROCESS、SELECT 权限,且能从运行 pt-table-checksum 的机器访问主库(注意网络策略和 bind_address)。别用 root@localhost,得是 root@'%' 或具体 IP 段。
- 用
mysql -h 主库IP -u 用户 -p -e "SELECT 1"先手动验证连通性 - 如果主库开了
skip-name-resolve,客户端 DNS 解析失败会导致超时,此时必须用 IP 连,不能写主机名 -
--recursion-method=none是常见误配:它禁用从库发现,但校验本身仍需主库;真想单点校验请用--replicate+ 手动指定从库 DSN
校验结果不显示不一致,不代表数据一致
pt-table-checksum 默认只在终端输出「checksum 完成」或「ERROR」,不打印每张表是否一致。真正的一致性结论藏在从库的 percona.checksums 表里,靠比对 this_crc 和 master_crc 字段。
常见误区是跑完命令看到 “Successfully completed” 就以为万事大吉。其实只要从库没同步上 checksum 记录(比如复制延迟、SQL 线程停了、replicate_do_table 过滤了 percona.checksums),结果就不可信。
- 查从库:
SELECT * FROM percona.checksums WHERE master_crc != this_crc OR ISNULL(master_crc) OR ISNULL(this_crc) - 检查复制状态:
SHOW SLAVE STATUS\G看Seconds_Behind_Master和SQL_Running - 如果用了 GTID,确认
--set-gtid-purged=OFF或已处理好 gtid_executed 覆盖问题,否则 checksum SQL 可能被从库拒绝执行
大表校验卡住或拖垮主库性能
pt-table-checksum 对每张表分块计算 CRC,块大小由 --chunk-size 控制。默认值往往偏大,尤其在没有合适索引的表上,容易触发全表扫描+临时表,导致主库 CPU/IO 暴涨、慢查询堆积、甚至阻塞业务写入。
它不是“后台悄悄跑”,而是实打实发 SELECT 查询到主库,再把结果发往从库比对。高并发写入场景下,频繁加锁(尤其是 --lock-wait-time 不够时)会让问题更糟。
- 先用
EXPLAIN看pt-table-checksum生成的分块语句是否走了索引,重点检查WHERE条件列是否有有效索引 - 调小
--chunk-size(如从默认 1000 改成 100),配合--chunk-index指定主键或唯一索引列 - 避开业务高峰,加
--sleep(如--sleep=0.1)让每块之间歇一歇,别一股脑冲 - 监控
Threads_running和Innodb_row_lock_waits,异常升高就得停
从库过滤规则会让 checksum 失效
如果从库开了 replicate_ignore_db、replicate_do_table 或 binlog_ignore_db,而 percona.checksums 表恰好落在被忽略的库或表里,那主库写的校验记录根本不会同步到从库——自然没法比对,所有表都显示“一致”,其实是假阴性。
更隐蔽的是 replicate_wild_ignore_table,比如设了 %.backup,但 percona 库名带下划线,某些版本 MySQL 会误匹配。
- 在从库执行
SELECT variable_name, variable_value FROM performance_schema.global_variables WHERE variable_name LIKE '%replicate%',逐条核对 - 确认
percona.checksums不在任何 ignore 规则范围内;最稳做法是把该表建在明确允许同步的库中(比如改用--replicate=test.checksums) - 用
--dry-run先看它准备执行哪些语句,检查是否含INSERT INTO percona.checksums,再确认该语句会不会被复制规则拦截
真正难的不是跑起来,是确认每一行 master_crc 都确实从主库来了、没被复制层吞掉、也没被从库 SQL 线程跳过——这些地方一漏,校验就白做。










