pt-table-checksum不能用于双向同步环境,因其默认仅支持单向主从拓扑,会误判节点角色、跳过校验方向、引发checksum表循环写入或连接混乱;强行使用需禁用自动发现、分方向手动配置DSN表、隔离replicate表且禁用GTID,但结果可信度低,推荐拆为两个单向链路分别校验。

pt-table-checksum 不能直接用于双向同步(Dual-Master / Circular Replication)环境的数据一致性校验——它默认只识别单向主从拓扑,会把双向链路中任一节点误判为“从库”而跳过另一方向,导致校验漏检甚至连接混乱。
pt-table-checksum 在双向同步下为什么会失效
- 工具依赖
SHOW SLAVE STATUS或SHOW PROCESSLIST自动发现从库,但在双向同步中,每个节点既是主库又是从库,SHOW SLAVE STATUS可能返回多个Master_Host,而pt-table-checksum只取第一个,其余被忽略 - 默认
--recursion-method=processlist会扫描所有连接线程,但无法区分“业务复制连接”和“双向同步连接”,容易连错实例或重复校验 - 若两个节点互为
MASTER,工具可能在校验 A→B 时,把 B 上正在执行的 B→A 的复制事务当成延迟,触发Waiting卡住 -
--replicate表写入后通过复制传播,双向环境下 checksum 结果会在两个节点反复来回写,造成percona.checksums表内容污染或主键冲突
如何强行让 pt-table-checksum 在双向同步中可用
必须放弃自动发现,完全手动控制校验路径:
- 使用
--recursion-method=dsn,并为每个校验方向单独建一张percona_schema.dsns表(注意:不是共享同一张) - 每次只校验一个方向:例如先在节点 A 上运行,只检查 A→B;再在节点 B 上运行,只检查 B→A
-
--replicate必须指向本地库表(如percona.checksums_a2b),且该表不参与复制(设replicate-ignore-table=percona.checksums_a2b),避免循环写入 - 关闭双向复制链路上的 GTID 自动定位(
SET GLOBAL gtid_mode=OFF临时操作),改用CHANGE MASTER TO MASTER_AUTO_POSITION=0,否则pt-table-checksum的语句可能被 GTID 跳过
示例(在节点 A 上校验 A→B):
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
pt-table-checksum \ --host=192.168.1.10 \ --user=chkuser --password='xxx' \ --replicate=percona.checksums_a2b \ --recursion-method=dsn=t=percona_schema.dsns_a2b \ --no-check-binlog-format \ --no-check-replication-filters \ --databases=mydb
其中 percona_schema.dsns_a2b 内容仅含 B 节点一行:
id dsn 1 h=192.168.1.11,u=chkuser,p=xxx,P=3306
为什么校验结果里 Diffs 总是 0,但实际数据明显不一致
- 双向同步中,
pt-table-checksum生成的校验 SQL 是基于 statement 复制的,若表里有NOW()、UUID()、@@server_id等非确定性函数,B 节点回放时值已不同,CRC 校验必然失败,但工具可能因超时或锁冲突跳过该 chunk,最终不报Diffs,只记Skipped -
percona.checksums_a2b表在 B 节点上被read_only=1阻止写入,checksum 值根本没落地,查不到差异是假阴性 - 某些 chunk 因无主键/唯一索引被迫全表扫,在双向同步高负载下频繁超时(
--chunk-time=0.5不够用),建议提前用SHOW CREATE TABLE检查,对缺失索引的表跳过或手工补索引
双向同步本身就不适合用 pt-table-checksum 做常态化校验。它本质是为单主多从设计的,强行适配代价高、结果可信度低。真正可靠的方案是:拆成两个独立单向链路,分别用 pt-table-checksum 定期校验;或改用逻辑层比对(如基于 binlog event 解析 + 行级 diff),绕过复制机制本身的干扰。










