pt-show-grants是percona toolkit中用于导出mysql用户grant语句的工具,能一键生成权限脚本但不可直接在新服务器执行;它原样导出授权记录,不校验语法兼容性、不处理版本差异或用户冲突,需人工检查identified with、角色、全局权限等适配问题。

pt-show-grants 是什么,能不能直接用?
pt-show-grants 是 Percona Toolkit 中的一个轻量级工具,专用于从 MySQL 提取用户权限并生成 GRANT 语句。它不依赖 mysqldump,也不导出数据或结构,只聚焦权限还原——这正是批量导出用户权限最干净的方式。
但注意:pt-show-grants 不是 MySQL 自带命令,需单独安装 Percona Toolkit;且要求连接用户具备 SELECT 权限访问 mysql.user、mysql.db、mysql.tables_priv 等系统表(通常 root 或 SUPER 权限用户才满足)。
怎么用 pt-show-grants 导出所有用户的权限脚本?
最常用的一条命令就能覆盖绝大多数场景:
pt-show-grants --host=localhost --user=root --password=xxx > all_grants.sql
关键点说明:
-
--host和认证参数必须显式指定,即使本地连接也不能省略--host(默认会走 socket,而pt-show-grants强制走 TCP) - 输出默认包含
CREATE USER IF NOT EXISTS+ 对应的GRANT语句,顺序合理,可直接 source 回库 - 若只想导出特定用户,加
--user=username;想排除匿名用户,加--skip-anonymous - 不加
--no-header时,开头会带注释说明生成时间与版本,不影响执行
导出的脚本为什么在目标库执行时报错?常见坑在哪?
直接 source all_grants.sql 到另一台 MySQL 实例时,失败往往不是语法问题,而是环境差异导致:
-
CREATE USER报ERROR 1396 (HY000): Operation CREATE USER failed:目标库已存在同名用户但密码哈希不同,pt-show-grants默认不加DROP USER,需手动加--drop参数重导(慎用!生产环境先确认) -
GRANT报ERROR 1133 (HY000): Can't find any matching row in the user table:说明CREATE USER语句没被执行(比如被注释、或因权限不足跳过),检查输出文件开头是否真有CREATE USER - MySQL 8.0+ 用户认证插件变化(如
caching_sha2_password):pt-show-grants会原样导出IDENTIFIED WITH ...,但若目标库未启用对应插件,需提前加载(INSTALL PLUGIN caching_sha2_password SONAME 'caching_sha2_password.so')或改用--set-vars="default_authentication_plugin=mysql_native_password"
不用 pt-show-grants,纯 SQL 能不能实现?
可以,但麻烦且易漏:MySQL 系统表分散在 mysql.user、mysql.db、mysql.tables_priv、mysql.procs_priv、mysql.proxies_priv,还要处理列权限、角色、密码过期策略等。
一个极简替代方案(仅覆盖全局+库级权限):
SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user;
然后把结果复制进客户端逐条执行,再重定向输出——但这只是“模拟”,不是真正导出可复用脚本。真要可靠、完整、支持 MySQL 5.7/8.0 的批量权限导出,pt-show-grants 仍是目前最省心的选择。
别忘了:导出前确认源库 sql_mode 不含 NO_AUTO_CREATE_USER(MySQL 5.7.21+ 已弃用,但旧实例可能还开着),否则 CREATE USER 语句会被拒绝。











