直接备份mysql库可行但需授权与绕过锁表:grant select on mysql.* to 'root'@'localhost';flush privileges;mysqldump必须加--skip-lock-tables,禁用--single-transaction;推荐仅导出user、db、tables_priv等核心权限表;还原后务必执行flush privileges。

直接备份 mysql 库是可行的,但 MySQL 8.0+ 默认禁止普通用户(含 root)对系统库执行 SELECT,不加处理会报 Access denied for user 'root'@'localhost' to database 'mysql' 或表被锁定。必须显式授权 + 绕过锁表机制,否则命令必然失败。
mysqldump 备份 mysql 库失败的常见原因
失败不是因为命令写错了,而是权限和参数双重限制:
-
SELECT权限缺失:MySQL 8.0+ 默认关闭root对mysql.*的SELECT,需手动补授:GRANT SELECT ON mysql.* TO 'root'@'localhost'; FLUSH PRIVILEGES; -
LOCK TABLES被拒:系统表(如user、role_edges)受保护,mysqldump默认尝试加锁,必须加--skip-lock-tables -
--single-transaction不兼容:该参数在 8.0+ 对mysql库无效,强制使用会报错Unknown table 'mysql.role_edges'类似提示 - 误用
-B简写:应始终用--databases mysql(而非-B mysql),否则导出不含CREATE DATABASE语句,还原时易出错
只导出用户与权限相关的核心表(推荐)
全量导出 mysql 库包含大量元数据(如 columns_priv、procs_priv),但日常迁移/审计真正需要的只有账号、密码、角色、权限分配逻辑。最轻量且安全的做法是显式指定关键表:
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:存用户名、host、authentication_string(密码哈希)、全局权限字段 -
db、tables_priv等:控制库/表/列/过程级权限 -
role_edges和default_roles:MySQL 8.0+ 角色机制必需,漏掉会导致角色无法生效 -
password_history(8.0.26+ 新增)可忽略,它不参与权限校验
导出后建议快速验证:grep -A2 "root.*localhost" users_and_privs.sql,确认关键账号字段完整。
还原后权限不生效?别跳过 FLUSH PRIVILEGES
这是生产环境最常踩的坑——导入 SQL 后以为完事了,结果新用户登不上、权限改了没反应。MySQL 不会自动重载内存中的权限缓存,必须手动触发:
mysql -u root -p -e "FLUSH PRIVILEGES;"
- 无论你是用
mysqldump全量还原,还是只导入user表,这一步都不可省 - 如果还原的是 GRANT 语句(如
source grants_backup.sql),这步仍需执行,因为部分权限变更不会被语句隐式刷新 - 在自动化脚本中,务必把
FLUSH PRIVILEGES写在导入命令之后,且确保执行成功(检查返回码)
真正复杂的地方不在命令本身,而在于权限模型的分层性:全局权限在 user 表,库级在 db 表,表级在 tables_priv,角色关系又依赖 role_edges —— 漏导任意一层,还原后行为就可能和预期不一致。动手前先确认目标 MySQL 版本,再决定要不要包含 role_edges 这类 8.0+ 特有表。











