mysqldump 备份 mysql 系统库需授权并加 --skip-lock-tables:先授予 root SELECT 权限,用 --databases 和 --skip-lock-tables 导出;8.0+ 不支持 --single-transaction;只导关键权限表更安全;还原后必须执行 FLUSH PRIVILEGES。
mysqldump 备份 mysql 系统库会失败?
直接用 mysqldump -u root -p mysql 导出会报错,常见错误是 access denied for user 'root'@'localhost' to database 'mysql' 或提示表被锁定。这是因为 mysql 8.0+ 默认禁用普通用户(包括 root)对 mysql 库的 select 权限,且部分系统表(如 user、role_edges)受安全策略保护。
必须用具备 SELECT + LOCK TABLES + SHOW DATABASES 权限的账户,并加 --skip-lock-tables 绕过锁表限制:
mysqldump -u root -p --skip-lock-tables --databases mysql > mysql_system_backup.sql
- 务必使用
--databases(不是-B的简写形式,避免歧义),否则导出不含CREATE DATABASE语句 - MySQL 5.7 可能还需加
--single-transaction;但 8.0+ 对mysql库不支持该参数,强制使用会报错 - 如果提示
Access denied,检查 root 是否有SELECT权限:运行SHOW GRANTS FOR 'root'@'localhost';,缺就补GRANT SELECT ON mysql.* TO 'root'@'localhost'; FLUSH PRIVILEGES;
只导出用户和权限,不带其他系统表
全量导出 mysql 库包含大量元数据(如 columns_priv、procs_priv),但日常迁移或审计往往只需要账号、密码、主机、角色和权限分配逻辑。最干净的做法是只 dump 关键表:
mysqldump -u root -p --skip-lock-tables mysql user db tables_priv columns_priv procs_priv proxies_priv role_edges default_roles > users_and_privs.sql
-
user表存账号、认证插件、密码哈希(authentication_string字段)、全局权限 -
db、tables_priv等控制库/表级权限;role_edges和default_roles是 MySQL 8.0+ 角色机制核心,漏掉会导致角色失效 - 注意:MySQL 8.0.26+ 新增
password_history表,它不参与权限控制,备份可忽略 - 导出后建议 grep 检查敏感字段是否完整:
grep -A2 "root.*localhost" users_and_privs.sql
导入时权限不生效?别跳过 FLUSH PRIVILEGES
还原 mysql 库后,MySQL 不会自动重载权限缓存,新用户或修改过的权限仍不可用。这是最容易被忽略的一步。
正确流程是:
mysql -u root -p mysql < mysql_system_backup.sql<br>mysql -u root -p -e "FLUSH PRIVILEGES;"
- 不能用
source命令在交互式客户端里执行 SQL 文件,因为CREATE USER等语句在非 SUPER 权限下可能被拒绝 -
FLUSH PRIVILEGES必须单独执行;即使 dump 文件末尾已含该语句,也不能依赖——MySQL 重启或某些版本下不会自动触发 - 如果导入后登录失败,先确认
user表中plugin字段值是否为caching_sha2_password(8.0 默认);目标实例若为 5.7,需提前改回mysql_native_password
mysqldump 不适合跨大版本迁移
MySQL 5.7 的 mysql 库结构和 8.0 差异极大(比如 8.0 移除了 Password 字段,新增 account_locked、password_reuse_history 等)。直接把 5.7 的 dump 导入 8.0 会报错,反之亦然。
- 跨版本迁移权限,推荐用
SELECT ... INTO OUTFILE提取纯文本账号信息,再用脚本生成兼容的CREATE USER/GRANT语句 - 例如导出所有非匿名用户:
SELECT CONCAT('CREATE USER ''',user,'''@''',host,''' IDENTIFIED WITH ',plugin,' AS ''',authentication_string,''';') FROM mysql.user WHERE user != ''; - 生产环境升级前,务必在测试实例上验证 dump 文件能否被目标版本解析——
mysql --no-defaults -u root -p -e "source users_and_privs.sql"就能看出语法兼容性问题
真正麻烦的从来不是导出命令怎么写,而是导出的内容在目标环境里能不能被正确识别、加载、生效。尤其是 plugin 类型、密码哈希格式、角色继承链这些细节,一不留神就卡住整个恢复流程。

















