MySQL无内置命令导出全部用户权限,需用mysqldump导出mysql.user、db、tables_priv、columns_priv、procs_priv、proxies_priv六张表并执行FLUSH PRIVILEGES恢复。

show grants 不能直接导出所有用户权限
MySQL 没有内置命令一键导出全部用户的 GRANT 语句,SHOW GRANTS FOR 'user'@'host' 只能查单个用户。硬写循环调用它容易漏掉匿名用户、空 host、或权限被 mysql.user 表里冗余字段(如 Super_priv)控制的场景。
常见错误是只遍历 mysql.user 表的 User 和 Host 列,却忽略:mysql.db、mysql.tables_priv 等库/表级权限,导致导出的 SQL 恢复后权限不全。
- 必须同时查
mysql.user、mysql.db、mysql.tables_priv、mysql.columns_priv、mysql.procs_priv五张表 -
SHOW GRANTS对存储过程权限(EXECUTE)支持不一致,5.7+ 才较稳定,旧版本得手动拼GRANT EXECUTE ON PROCEDURE - 注意
''@'localhost'这类空用户名(匿名用户),SHOW GRANTS会报错,得用条件过滤或跳过
用 mysqldump 导出权限表最稳妥
绕过 SHOW GRANTS 的局限,直接 dump 权限元数据表更可靠——这些表结构稳定,且恢复时 MySQL 自动校验逻辑。但要注意:不能只 dump mysql.user,否则库级权限丢失。
实操命令要覆盖全部权限相关表:
mysqldump --single-transaction --skip-triggers --compact mysql user db tables_priv columns_priv procs_priv proxies_priv > mysql_grants_backup.sql
-
--single-transaction防止导出过程中权限变更导致不一致 - 必须显式列出所有权限表名,
mysqldump mysql默认不包含procs_priv等非核心表 -
--skip-triggers避免误导出mysql库里的触发器(实际不存在,但参数保险) - 导出文件不含
CREATE DATABASE或DROP TABLE,恢复时需先确保mysql库存在
用 SELECT + CONCAT 拼接可执行的 GRANT 语句
如果非要生成人类可读、可直接 source 的 GRANT SQL(比如做权限审计或跨版本迁移),就得自己拼。核心是把权限表字段翻译成标准语法,尤其注意引号和转义。
关键点在 mysql.user 表的权限字段(如 Select_priv)要映射为 'Y' → SELECT,且 host 要用单引号包裹:
SELECT CONCAT('GRANT ', privilege, ' ON ', scope, ' TO ''', User, '''@''', Host, ''';')
FROM (
SELECT User, Host, 'SELECT' AS privilege, '*.*' AS scope FROM mysql.user WHERE Select_priv = 'Y'
UNION ALL
SELECT User, Host, 'INSERT', 'db1.*' FROM mysql.db WHERE Db = 'db1' AND Insert_priv = 'Y'
) t;
-
CONCAT结果里所有字符串值(User、Host、库名)必须用两个单引号包裹,否则恢复时报语法错 - 全局权限(
*.*)和库级权限(db.*)的ON子句格式不同,不能混用 -
mysql.tables_priv里的权限字段是逗号分隔字符串(如'Select,Insert'),得用FIND_IN_SET拆解,不是简单等值判断
恢复时权限不生效?检查 sql\_mode 和 FLUSH PRIVILEGES
导出的权限 SQL 恢复后,用户连不上或权限变少,大概率不是导出问题,而是恢复流程没走完。
常见现象:source mysql_grants_backup.sql 成功,但 SHOW GRANTS FOR 'u'@'h' 还是旧结果。
- 如果是用
mysqldump导出的表数据,恢复后必须执行FLUSH PRIVILEGES—— MySQL 不自动重载内存中的权限缓存 - 如果目标实例
sql_mode包含STRICT_TRANS_TABLES,而导出的mysql.user表里有空字符串密码(authentication_string = ''),插入会失败,权限丢失 - MySQL 8.0+ 默认用
caching_sha2_password插件,若导出的是老版本mysql_native_password用户,恢复后需手动ALTER USER ... IDENTIFIED WITH mysql_native_password
权限备份不是“dump 就完事”,FLUSH PRIVILEGES 是最后一道必须踩的脚踏板,漏了就等于没恢复。


















