唯一可靠路径是在主库运行pt-table-checksum写入percona.checksums表,依赖复制同步到从库比对;在从库直接执行会因权限、复制状态或变量问题失败。

直接在主库上运行 pt-table-checksum,结果写入 percona.checksums 表,靠复制机制自动同步到从库比对——这是唯一可靠路径。备份恢复后若跳过这步,你根本不知道从库哪张表、哪几行数据已“静默损坏”。
为什么不能在从库上直接跑 pt-table-checksum
工具设计依赖主从复制链路:它在主库生成校验 SQL(如 REPLACE INTO ... SELECT CRC32(...) FROM t1 WHERE id BETWEEN ? AND ?),再靠 binlog 把这条语句“推”到从库执行并重算一次校验和。如果你把 --host 指向从库,它会尝试在从库上模拟主库行为(比如改 binlog_format、查 SHOW PROCESSLIST 找 slave),但权限缺失、复制状态异常或变量不可写,大概率卡死或报错:Cannot connect to host 或 Replica mysql2 is stopped. Waiting.。
备份恢复后常见陷阱:
- 从库的
Slave_IO_Running和Slave_SQL_Running看似为Yes,但Seconds_Behind_Master可能是NULL(IO 线程假活)或远超预期; - 恢复时用了
mysqldump --single-transaction,但没加--master-data=2,导致从库起始位点错误,后续所有校验都无效; - 备份文件里含
SET SQL_LOG_BIN=0,恢复时跳过了 binlog,percona.checksums表压根没同步过去。
pt-table-checksum 必须满足的硬性前提
备份恢复完成后,别急着跑命令,先确认这五件事:
- 主库账号有完整权限:
SELECT, INSERT, UPDATE, REPLICATION SLAVE, PROCESS, SUPER; - 主库已存在
percona库:CREATE DATABASE IF NOT EXISTS percona;; - 所有待校验表都有主键或非空唯一索引(否则跳过,输出
No good index); - 主库
binlog_format是ROW时,必须加--no-check-binlog-format,否则直接退出; - 从库延迟不能长期卡在阈值外——默认
--max-delay=1秒,备份刚恢复完常有几十秒延迟,建议临时放宽:--max-delay=60。
执行校验时的关键参数与避坑点
基础命令示例(主库执行):
pt-table-checksum \ --replicate=percona.checksums \ --no-check-binlog-format \ --no-check-replication-filters \ --max-delay=60 \ --databases=myapp_db \ h=192.168.5.100,u=chk,p=secret
重点说明:
-
--replicate=percona.checksums:必须显式指定,不能依赖默认值——有些环境默认库名不是percona; -
--no-check-replication-filters:备份恢复后常启用了replicate-do-db类过滤,不加这个参数会漏检被过滤的库; - 不要用
--replicate-check-only预览——它只查percona.checksums表中已有记录,而备份恢复后该表为空,结果永远显示“0 diffs”; - 校验过程会给表加
S锁(共享锁),大表可能阻塞UPDATE/DELETE,观察SHOW PROCESSLIST中是否有长时间Waiting for table level lock; - 输出里看
DIFFS列是否为非零值,忽略TS(时间戳)和ROWS(行数)——它们只反映校验进度,不表征一致性。
如何快速定位备份恢复后的真实不一致块
校验命令跑完后,立刻连从库查:
SELECT db, tbl, chunk, lower_boundary, upper_boundary, this_crc, master_crc, DIFFS FROM percona.checksums WHERE (master_crc IS NULL AND this_crc IS NOT NULL) OR (master_crc IS NOT NULL AND this_crc IS NULL) OR (master_crc != this_crc) OR DIFFS != 0;
注意两个易忽略点:
- 如果某块的
master_crc为NULL,说明主库没成功写入该校验和(可能是权限不足或表结构变更导致分块失败),不能简单认为“从库多了一行”,得回主库查日志; - 备份恢复后若从库
relay_log被清空过,percona.checksums表虽已同步,但部分块的校验 SQL 可能因 relay 日志缺失而未执行——此时需手动检查SHOW SLAVE STATUS的Relay_Log_File和Relay_Log_Pos是否连续。
最麻烦的情况是:校验结果显示一致,但业务查询仍出错。这时候问题往往不在数据本身,而在备份时未导出函数、视图或触发器定义,或者从库字符集与主库不一致(如主库 utf8mb4_0900_as_cs,从库仍是 utf8mb4_general_ci)——校验工具完全不检查这些元数据。











