pt-table-sync 不用于结构比对,它只同步数据;正确做法是用 mysqldump --no-data 配合参数裁剪和预处理(如排序 KEY、过滤注释、统一字符集等)生成可比 DDL,再 diff。
用 pt-table-sync 做结构比对?别踩这个坑
它根本不是干这个的——pt-table-sync 只同步数据,不校验表结构。强行用它“发现差异”,只会漏掉 default 改变、comment 变更、索引顺序调整这些关键项。
真正该用的是 pt-online-schema-change 的配套工具 pt-show-grants 和原生 mysqldiff,但后者依赖 MySQL Utilities(已弃用),所以现在最稳的路径是:用 mysqldump --no-data + diff 手动比对。
- 必须加
--skip-extended-insert,否则自增 ID、时间戳等干扰项会让 diff 失效 - 统一用
--skip-comments,避免注释格式差异(比如某实例用/*!50100 ... */,另一台没开)引发误报 - 导出前先
SET SESSION sql_mode='',防止不同实例 sql_mode 导致CREATE TABLE语句生成不一致
如何让 mysqldump --no-data 输出可比对的干净 DDL
默认导出会混入 CREATE DATABASE、USE、字符集声明、引擎参数,这些在多实例间天然不一致(比如一台用 utf8mb4_0900_as_cs,另一台还是 utf8mb4_general_ci),直接 diff 会满屏红色。
正确做法是只保留核心结构定义,靠参数裁剪:
- 加
--no-create-db --skip-triggers --skip-routines --skip-events,砍掉所有非表结构内容 - 用
--set-gtid-purged=OFF避免 GTID 相关行污染输出 - 强制指定
--default-character-set=utf8mb4,统一字符集声明,不然有的实例写CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs,有的只写CHARSET=utf8mb4
示例命令:
mysqldump -h host1 -u user -p --no-data --no-create-db --skip-triggers --skip-routines --skip-events --set-gtid-purged=OFF --default-character-set=utf8mb4 db_name table_name > host1_table.sql
对比时为什么 diff 总报一堆“无关差异”
不是 diff 不行,是没预处理。MySQL 的 DDL 输出顺序本身就不稳定:索引定义可能在字段后,也可能在末尾;PRIMARY KEY 有时单独一行,有时跟在字段后面;分区信息位置更随机。
解决方法不是换工具,而是标准化输出顺序:
- 用
sed把所有KEY、UNIQUE KEY、PRIMARY KEY行提取出来,单独排序再合并回去(awk '/^ KEY|^ UNIQUE KEY|^ PRIMARY KEY/ {print; next} {print}' | sort) - 用
grep -v '^--' | grep -v '^/'过滤掉注释和分隔线 - 最后用
sort | uniq -u快速定位仅存在于一方的字段或索引(比全文 diff 更准)
跨版本 MySQL(5.7 vs 8.0)比对要注意什么
8.0 默认开启 sql_require_primary_key,且 JSON 字段、隐藏主键、降序索引语法都和 5.7 不兼容。直接 dump 出来比,会把语法差异当成结构差异。
稳妥做法是降级兼容输出:
- 在 8.0 实例上加
--skip-create-options,避免导出ALGORITHM=INSTANT或STORAGE DISK这类 5.7 不认识的参数 - 手动替换
JSON为TEXT(如果业务允许),或统一用LONGTEXT占位,否则 diff 会卡在类型名上 - 禁用 8.0 新特性:连接时加
--mysql-version=5.7(部分客户端支持),或用SELECT * FROM information_schema.COLUMNS自己拼 DDL,绕过 mysqldump 的版本感知逻辑
真正麻烦的不是语法,是隐式行为——比如 8.0 的 TIMESTAMP 默认带 NOT NULL DEFAULT CURRENT_TIMESTAMP,而 5.7 不带。这种差异不会报错,但会导致应用插入空值失败。得靠脚本扫描 COLUMN_DEFAULT 字段做二次校验。










