
为什么 pt-table-checksum 报错 “Cannot replicate row-based events”
主从切换后或开启 binlog_format=ROW 时,pt-table-checksum 默认用语句级校验(SBR),但从库无法重放 INSERT/UPDATE 的 checksum 语句,直接报这个错。
- 必须显式加
--replicate-check-only或改用--chunk-index配合主键,避免生成不可复制的语句 - 更稳妥的做法是统一设
binlog_format=STATEMENT(仅在校验期间临时改,且确保所有语句都确定性) - 如果只能用 ROW 模式,务必加
--no-check-binlog-format并确认从库已启用log_slave_updates,否则 checksum 表变更不会写入从库 binlog,导致结果永远不一致
pt-table-checksum 扫描卡在某个表不动了怎么办
常见于大表无合适索引、或 WHERE 条件无法下推到存储引擎层,导致全表扫描 + 大量锁等待。
- 先用
SHOW PROCESSLIST看卡在哪条SELECT,重点查是否在扫描WHERE (id >= ? AND id 这类分块语句 - 给分块字段(通常是主键或唯一索引)加
FORCE INDEX:加参数--chunk-index=PRIMARY显式指定 - 调小
--chunk-size(比如从 1000 改成 100),减少单次扫描压力;同时加--chunk-time=0.1让工具自动动态调优 - 避开业务高峰执行,否则容易触发
Waiting for table metadata lock
从库显示有差异,但 pt-table-sync 却不输出 SQL
不是数据没差,而是 pt-table-sync 默认只输出“能安全修复”的差异——它会跳过没有主键/唯一键的表、跨字符集的列、或检测到从库有未应用的 relay log。
- 加
--print看它到底发现什么差异,再加--verbose查跳过原因(常见提示:Skipping table because no unique index) - 确认从库
Seconds_Behind_Master = 0且Slave_SQL_Running = Yes,否则同步工具认为“状态不可信”,直接放弃 - 如果表真没主键,别硬用
--sync-to-master,先人工比对几行,再考虑加临时唯一索引或导出重建
校验结果里 DIFFS 列为 1,但 pt-table-sync --print 没输出任何行
这是最让人困惑的情况:checksum 表里记录了差异,但同步工具找不到可修复的行。根本原因是校验和计算方式与同步逻辑不完全对齐——比如某列是 TIMESTAMP 类型,主从时区不同导致值不同,但 pt-table-sync 默认忽略时间类型列的微小差异。
- 加
--columns显式列出要校验的列(排除updated_at等易变字段),让两边计算口径一致 - 检查
pt-table-checksum是否用了--ignore-columns,而pt-table-sync没同步这个配置 - 最保险的方式:用
--replicate=test.checksums指定校验表,然后直接查该表,看DIGEST值是否真不同,而不是只信DIFFS计数
真正难的不是跑通命令,是理解 checksum 表里那串 DIGEST 值怎么算出来的,以及它和你实际看到的数据之间隔了几层隐式转换。










