pt-table-checksum执行后没报错但从库仍不一致,根本原因在于它默认仅在主库计算并写入校验和到percona.checksums表,是否同步到从库依赖复制延迟、binlog格式(如statement下now()导致crc32不一致)、replicate_ignore_db等过滤规则,且工具本身不主动连接从库比对;必须手动查从库的percona.checksums表中master_crc与this_crc差异,或配合--replicate-check-only强制校验从库。

为什么 pt-table-checksum 执行后没报错,但从库数据还是不一致?
pt-table-checksum 默认只校验主库,把校验结果写入主库的 percona.checksums 表,并不主动连接从库比对。它依赖从库重放这些 checksum 记录(通过 binlog 复制),再由 pt-table-sync 或手动查询从库的 percona.checksums 表来发现差异。
常见错误现象包括:
- 主库执行完
pt-table-checksum,直接看输出“0 differences found”,就认为一致 - 从库延迟高或复制中断过,
percona.checksums表没及时更新,导致比对失效 - 从库开启了
replicate_ignore_db或replicate_do_table,跳过了percona.checksums表的同步
实操建议:
- 执行前确认从库 SQL 线程运行中:
SHOW SLAVE STATUS\G中Slave_SQL_Running: Yes且Seconds_Behind_Master接近 0 - 强制让
pt-table-checksum同时校验从库(需从库可连):--replicate-check-only配合--databases指定库,但前提是主从都已写入 checksums 表 - 校验完成后,必须登录从库执行:
SELECT * FROM percona.checksums WHERE this_crc != master_crc OR is_bad = 1;
pt-table-checksum 连接从库失败:Access denied 或 Lost connection
工具默认用主库账号连接所有实例,但很多生产环境从库禁止远程写入、禁用 SUPER 权限,甚至只开放读账号。而 pt-table-checksum 在从库上需要 SELECT 权限(查 percona.checksums),某些模式下还需 INSERT/UPDATE(如 --replicate 写校验值)。
权限与连接关键点:
- 主库账号至少要有:
REPLICATION CLIENT,PROCESS,SELECT,INSERT,UPDATE,DELETE(对percona库) - 从库若用独立账号,需在
--recursion-method=dsn中显式指定:--recursion-method="dsn=t=percona.dsns",并在percona.dsns表里填从库 host/user/pass - 避免使用 root@'%' 这类宽泛账号——MySQL 8.0+ 默认禁用密码过期策略,但远程连接可能被防火墙或 bind-address 拦截;优先用
localhost走 socket 连主库,用内网 IP 连从库
校验大表卡住、锁表或拖慢业务怎么办?
pt-table-checksum 对每张表按 chunk 分片校验,默认用主键或唯一索引做范围扫描。但若表无合适索引、或 chunk 太大,会导致单次查询超时、长事务堆积、甚至触发 MDL 锁阻塞 DML。
影响与缓解方式:
- 不要对正在频繁写入的大表(如订单流水)直接全量校验;加
--chunk-size=1000控制每次扫描行数 - 用
--chunk-index指定高基数且稳定的索引(避免用状态字段等低区分度列) - 加
--max-load="Threads_running=25"自动暂停,当主库SHOW STATUS LIKE 'Threads_running'超限时会 sleep - 禁用自动分析(避免
ANALYZE TABLE干扰):--no-check-plan - 生产环境务必加
--dry-run先试跑,观察慢日志和SHOW PROCESSLIST
为什么 pt-table-sync 生成的 SQL 在从库执行时报错:Duplicate entry 或 No such table?
pt-table-sync 默认生成修复语句时,是基于主库为“权威源”反向推导从库缺失/多余的数据,但它不会判断从库是否真能执行这些语句——比如:
- 从库有额外唯一约束或触发器,导致 INSERT 冲突
- 主库删了某张表,但从库还没同步到 DROP 语句,此时
pt-table-sync --sync-to-master仍试图往该表写数据 - 时间戳字段含
NOW()或CURRENT_TIMESTAMP,主从时钟偏差导致 WHERE 条件失效
安全操作底线:
- 永远先用
--print输出 SQL,人工核对 3–5 条典型语句的逻辑(尤其注意 WHERE 子句是否含函数或非确定性表达式) - 不要直接
--execute到从库;应先--sync-to-master生成主库可执行语句,再在主库执行(靠复制传播到从库) - 若从库有业务写入(非纯从库),必须停写或切走流量,否则修复过程中新数据会再次破坏一致性
主从一致性不是一次校验就能一劳永逸的事。checksum 的本质是快照比对,而复制延迟、网络丢包、隐式类型转换、SQL_MODE 差异,都会让两次校验之间悄然产生偏差。最常被忽略的是:没定期清理 percona.checksums 表的历史记录,导致后续校验变慢甚至 OOM。











