mysqldump 默认不导出 MySQL 系统库权限表(如 user、db 等),需 root 或高权限账号显式指定表并加 --skip-triggers;恢复后必须执行 FLUSH PRIVILEGES,否则权限不生效。

mysqldump 备份 mysql 系统库时为什么权限没导出
默认 mysqldump 不会备份 mysql 库里的权限表(如 user、db、tables_priv),除非显式指定,且需足够权限。
- 普通用户执行
mysqldump mysql会报错:Access denied for user ... to database 'mysql' -
--all-databases也跳过mysql库,除非加--skip-lock-tables和高权限账号(如 root) - 即使能连上,
mysqldump默认忽略mysql库中的部分系统表(尤其是 8.0+ 的role_edges、password_history等),需配合--include-tables或手动指定表
用 mysqldump 正确导出用户与权限的命令组合
必须用具有 SELECT 权限的 root 或具备 BACKUP_ADMIN + SYSTEM_VARIABLES_ADMIN 的账号(MySQL 8.0.21+)。
- 导出全部权限相关表:
mysqldump --single-transaction --skip-triggers mysql user db tables_priv columns_priv procs_priv proxies_priv --result-file=privs.sql - MySQL 8.0+ 还要加:
role_edges default_roles password_history,否则角色授权会丢失 - 务必加
--skip-triggers:系统库中这些表不含触发器,但不加可能触发意外警告或失败 - 避免用
--databases mysql:它会生成CREATE DATABASE语句,在目标实例上执行可能报错(库已存在)
恢复权限表时为什么用户登录失败或权限不生效
直接 source privs.sql 很可能让权限失效,因为 MySQL 服务端缓存了权限、且某些表有严格写入顺序和校验逻辑。
- 不能只恢复单个表(如只恢复
user):权限是多表联合生效的,db表没同步会导致数据库级权限丢失 - 恢复后必须执行:
FLUSH PRIVILEGES;,否则内存中权限缓存未更新 - MySQL 8.0+ 使用 caching_sha2_password 插件时,
user表里plugin和authentication_string字段必须匹配,否则用户无法登录 - 如果目标实例开启了
read_only=ON,恢复前需临时关闭:SET GLOBAL read_only = OFF;
替代方案:用 SELECT INTO OUTFILE + LOAD DATA 更可控
当 mysqldump 因权限或版本差异不可靠时,可逐表导出文本再加载,适合跨大版本迁移(如 5.7 → 8.0)。
- 导出用户信息:
SELECT Host,User,Select_priv,Insert_priv,... FROM mysql.user INTO OUTFILE '/tmp/user.txt' FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'; - 注意:路径必须是 MySQL 服务端可写目录,且需
FILE权限;secure_file_priv限制实际可写路径 - 导入前清空目标表(谨慎!):
TRUNCATE TABLE mysql.user;,再LOAD DATA INFILE '/tmp/user.txt' INTO TABLE mysql.user ... - 表间依赖顺序不能错:先
user,再db,再tables_priv,最后FLUSH PRIVILEGES;
FLUSH PRIVILEGES。少一步,用户就登不上。










