主从中断时先怀疑Schema不一致,因SQL_THREAD_STOPPED且Seconds_Behind_Master为NULL、Last_SQL_Error提示列数或字段名不匹配;pt-table-checksum不能检测Schema不一致,仅校验行级数据一致性,需先用pt-table-sync --dry-run或mysqldump -d -n -t对比结构,再配置binlog_format=STATEMENT、read_only=0等参数运行checksum。

主从中断时,为什么先怀疑 Schema 不一致?
因为 SHOW SLAVE STATUS\G 中出现 SQL_THREAD_STOPPED 且 Seconds_Behind_Master: NULL,同时 Last_SQL_Error 显示类似 Column count doesn't match value count at row 1 或 Unknown column 'xxx' in 'field list' —— 这类错误几乎都指向主从表结构不一致,而非数据内容差异。Schema 不一致会直接让从库 SQL 线程解析 binlog 失败,比数据不一致更早、更硬性地中断复制。
pt-table-checksum 能查 Schema 不一致吗?
不能。这是最常踩的坑:pt-table-checksum 只校验**行级数据一致性**,它依赖主从表结构完全相同(字段名、顺序、类型、是否允许 NULL),一旦 Schema 不一致,工具自身就会报错退出,比如:
Cannot connect to DSN 'h=127.0.0.1,P=3306,u=checksum,...': Table structure differs on master and slave: ...
所以它的作用不是“发现 Schema 不一致”,而是:在确认 Schema 一致的前提下,快速定位哪些表/哪些 chunk 的数据存在差异。用它之前,必须先做 Schema 对比。
怎么高效对比主从 Schema?
别手动 SHOW CREATE TABLE 逐个比对。推荐两个实操路径:
- 用
pt-table-sync --print --sync-to-master配合--dry-run:它会扫描所有表,遇到结构差异时直接报错并输出具体字段差异(如某列在主库是VARCHAR(255),从库是TEXT),适合批量发现; - 直接导出结构再 diff:
mysqldump -h$MASTER -d -n -t --skip-triggers database_name > master.sql,同理导出从库结构,然后diff master.sql slave.sql;注意加-d(no-data)、-n(no-create-db)、-t(no-create-info)保证只比结构,避免 AUTO_INCREMENT 值干扰; - 检查关键隐性差异:字段默认值(尤其是
DEFAULT CURRENT_TIMESTAMP在低版本 MySQL 不兼容)、生成列(generated columns)、索引顺序、外键约束(从库可能被禁用FOREIGN_KEY_CHECKS导致缺失)。
Schema 对齐后,再用 pt-table-checksum 的关键参数
Schema 一致只是前提,真正跑通 pt-table-checksum 还得避开几个典型配置雷区:
- 主库必须开启
binlog_format=STATEMENT(或至少 MIXED),ROW 格式下该工具无法工作; - 从库需设置
read_only=0(否则 checksum 表写入失败); - 务必指定
--replicate=test.checksums并确保该库表在从库可写; - 大表建议加
--chunk-size=10000和--chunk-time=0.5控制节奏,避免锁表过久; - 执行完后,立刻在从库查
SELECT * FROM test.checksums WHERE this_crc != master_crc OR is_drift —— 注意不是看返回行数,而是看 <code>is_drift字段是否为负值,这才是真实的数据漂移标记。
Schema 是复制的基石,而 pt-table-checksum 是建好房子后的验房工具。很多人卡在第一步却以为问题出在第二步,结果反复重跑 checksum,却始终没发现从库少了个 NOT NULL 约束或者多了一个隐形的 GENERATED ALWAYS AS 字段。











