必须先运行 pt-table-checksum 生成校验表,再用 pt-table-sync 依据该校验表修复,因后者不检测差异;--sync-to-master 模式下修复语句须在主库执行以保障复制一致性;关键参数 --chunk-size、--max-load、--recursion-method 缺一不可。

能在线修复,但必须先确认不一致范围、停写入干扰、用 pt-table-sync 配合 pt-table-checksum 执行,不能直接 --execute。
为什么不能跳过 pt-table-checksum 直接跑 pt-table-sync
因为 pt-table-sync 本身不检测差异,它只依赖 pt-table-checksum 写入的校验表(如 percona.checksums)来定位哪张表、哪个 chunk 不一致。没有这个表,--sync-to-master 会报错或误判。
常见错误现象:Cannot find table percona.checksums 或输出大量 “no differences found” 却实际有数据偏差。
- 必须在主库上先执行
pt-table-checksum,且参数要匹配从库可见的校验表路径,例如--replicate=percona.checksums - 主库执行时需确保从库能通过复制账号读取该表,否则从库无法同步校验结果
- 若主库 binlog_format 是
STATEMENT,需加--no-check-binlog-format,否则工具会拒绝运行
pt-table-sync --print 输出的 SQL 为什么不能直接在从库执行
因为 --sync-to-master 模式下,pt-table-sync 生成的修复语句默认在主库执行(再靠复制同步到从库),而不是直接改从库。如果手动把 --print 出来的 SQL 拿到从库执行,可能破坏 GTID 序列、触发主键冲突、绕过复制过滤规则。
典型错误场景:输出里出现 REPLACE INTO 或 DELETE,但在从库执行后,主库没同步这条变更,导致后续复制报错 1062 Duplicate entry 或 1032 Can't find record。
- 始终用
--sync-to-master h=从库IP指定目标从库,让工具自动决定在哪执行修复逻辑 - 预览时加
--verbose可看到每条 SQL 的执行位置(主库 or 从库)和影响行数 - 若必须直改从库(如 GTID 模式下跳过某事务后需补数据),应改用
--sync-from-master模式,并确保从库已设为read_only=0
修复过程中哪些参数最容易被忽略却影响成败
三个关键参数不设对,轻则修复失败,重则锁表或拖垮主库性能。
-
--chunk-size:默认按 1000 行分块校验。大表(千万级+)建议调小(如500),避免单次查询超时或内存溢出 -
--max-load:例如--max-load="Threads_running=25",防止修复过程加重主库负载。不设的话,高峰期可能把主库 CPU 拉满 -
--recursion-method:默认用processlist发现从库。若主库权限受限或网络隔离,需显式指定--recursion-method=dsn=t并提供从库 DSN 列表
另外,--databases 和 --tables 必须精确匹配 pt-table-checksum 时的范围,否则会漏修或报错 Table does not exist in checksum table。
修复后验证不一致是否真消失的可靠方式
别只看 SHOW SLAVE STATUS 的 Seconds_Behind_Master=0 —— 这只说明复制追上了,不代表数据一致。
真正有效的验证是再次跑 pt-table-checksum,并检查 percona.checksums 表里的 diff_cnt 字段是否全为 0。如果有非零值,说明上次修复没覆盖全部 chunk,或期间又有新写入干扰。
- 修复完成后至少等 1–2 分钟再校验,避开复制延迟窗口
- 若仍存在
diff_cnt > 0,优先查last_update时间戳是否最新,排除 checksum 表未同步到从库的可能 - 某些场景(如 MEMORY 表、含函数的计算列)天然无法被
pt-table-checksum正确比对,需单独处理
最易被忽略的一点:修复全程主库不能执行 FLUSH TABLES WITH READ LOCK,否则 pt-table-sync 会因等待锁而卡死;它本身设计就是无锁在线修复,强行加锁反而破坏前提。


















