pt-schema-digest 非 mysql 自带,需安装 percona toolkit;默认仅哈希比对结构,加 --verbose 或 --no-column-order 等参数才能暴露细节差异;需授权 select、show view、lock tables、process;输出 diff 不展开字段级差异,建议结合 --print 或 mysqldump -d 后用 diff 对比。

pt-schema-digest 找不到命令或报错 command not found
这个工具不属于 MySQL 自带,是 Percona Toolkit 的一部分,得单独装。很多人直接搜“MySQL 查表结构差异”,下意识以为它是 mysql-client 附带的,结果一跑就报 pt-schema-digest: command not found。
- Linux(Debian/Ubuntu):用
apt install percona-toolkit,别只装percona-server-tools,那个不含pt-schema-digest - CentOS/RHEL:先配 Percona 官方源,再
yum install percona-toolkit;用dnf的也一样,别漏掉-y否则可能卡在确认环节 - Mac:
brew install percona-toolkit可行,但注意 Homebrew 默认装的是最新版,某些老 MySQL 版本(比如 5.6)可能因协议不兼容报Authentication plugin 'caching_sha2_password' cannot be loaded—— 这时候得加--defaults-file指定含default-auth = mysql_native_password的配置文件
对比两个库的同一张表,但输出里没看到结构差异
pt-schema-digest 默认只做“校验和比对”,不是直接 diff DDL。它先把表结构转成规范化的哈希值,再比哈希——所以如果两张表字段顺序不同、注释不同、但实际列名/类型/长度/是否为空都一致,哈希值仍可能相同,输出就显示“无差异”。
- 必须加
--verbose才能看到每张表生成的规范化结构串,方便人工核对哪里被标准化掉了 - 如果想强制暴露字段顺序差异,得配合
--no-column-order(但该参数仅在较新版本支持,v3.5.0+) - 注意默认忽略
COMMENT和COLLATE,要让它们参与比对,得显式加--include-comment和--include-collation - 它不比较索引名称、外键名称,只比索引字段组合和类型;如果只是索引名从
idx_user_id改成user_id_idx,不会触发差异告警
运行时卡住或报错 Access denied for user
这个工具需要读取 INFORMATION_SCHEMA 和部分系统表,权限比普通查询高。很多 DBA 给应用账号只开了 SELECT,但 pt-schema-digest 还要 SHOW CREATE TABLE、SHOW TABLE STATUS,甚至临时建表验证(取决于选项)。
- 最低权限组合是:
SELECT, SHOW VIEW, LOCK TABLES, PROCESS;如果还用了--check-replication-filters,还得加REPLICATION CLIENT - 别用 root 账号硬上,尤其跨环境(比如从测试库连生产库),容易因主机白名单或密码策略失败;建议专门建个只读比对账号:
CREATE USER 'schema_diff'@'%' IDENTIFIED BY 'xxx'; GRANT SELECT, SHOW VIEW, LOCK TABLES, PROCESS ON *.* TO 'schema_diff'@'%'; - 如果目标库开了
sql_mode=STRICT_TRANS_TABLES,而工具生成的临时语句含隐式转换,可能直接中断;此时加--set-vars sql_mode=''临时绕过(执行完记得恢复)
输出结果里有 DIFF 但看不出具体哪列不同
pt-schema-digest 的原始输出是紧凑哈希比对,DIFF 行只告诉你“这张表结构不一致”,不展开字段级差异。真要定位到 created_at 缺少 DEFAULT CURRENT_TIMESTAMP,得靠辅助手段。
- 先用
--print把两边结构分别导出:pt-schema-digest --host=host1 --databases=db1 --tables=t1 --print > t1_host1.sql,再换 host2 重跑一次,最后用diff t1_host1.sql t1_host2.sql - 更省事的是结合
mysqldump -d(-d 表示 no-data):mysqldump -h host1 -u u -p -d db1 t1 | sed '/^--/d;/^$/d' > t1_h1.sql,清理注释空行后再 diff - 注意
pt-schema-digest对 enum/set 值排序是按字典序重排过的,而mysqldump保持定义顺序——如果 enum 值顺序不一致,diff会报大量假阳性,这时得先统一排序再比
真正麻烦的是跨版本比对,比如 MySQL 5.7 和 8.0 之间,JSON 字段的默认值写法、隐藏索引语法、不可见列这些特性,工具不一定能归一化处理,得人工盯住版本说明文档里的 DDL 变更点。











