mysqlpump --exclude-databases=% --users 是mysql 8.0+最简可靠的用户权限导出方式,可完整导出用户、密码哈希及权限语句并自动适配caching_sha2_password格式,而mysqldump --all-databases不导出mysql.user表导致权限丢失。

mysqlpump --users 是最简可靠的导出方式
MySQL 8.0+ 环境下,mysqlpump --exclude-databases=% --users 能一次性生成所有用户、密码哈希和权限语句,且自动适配 caching_sha2_password 插件格式。它比 mysqldump --all-databases 可靠得多——后者根本不会导出 mysql.user 表内容,权限直接丢失。
注意两点:
-
mysqlpump要求 MySQL 5.7.8+,8.0 推荐使用;若版本太低(如 5.6),该命令不存在,必须换方案 - 执行时需有
SELECT权限访问mysql库,普通账号不行,得用root或带SYSTEM_USER权限的账号
手动拼 GRANT 语句时必须查 plugin 和 authentication_string
直接从 mysql.user 表拼 CREATE USER,字段名和值在不同版本差异极大:5.7 用 password 字段,8.0 改为 authentication_string;认证插件也从 mysql_native_password 变成默认 caching_sha2_password。硬编码字段会失败。
安全做法是用以下查询(适配 5.7+):
SELECT CONCAT('CREATE USER IF NOT EXISTS \'', User,'\'@\'', Host,'\' IDENTIFIED WITH ', plugin,' AS \'', authentication_string,'\';')
FROM mysql.user
WHERE User NOT IN ('mysql.session','mysql.sys');
常见坑:
- 漏掉
IF NOT EXISTS,导入时遇到同名用户报错中断 - 没过滤系统用户(如
mysql.session),导致目标库启动异常 - 没显式指定
plugin,新库可能用默认插件创建用户,但密码哈希是旧插件格式,登录失败
迁移后连接失败?先检查 caching_sha2_password 兼容性
应用连不上,错误提示 Authentication plugin 'caching_sha2_password' cannot be loaded,说明客户端不支持该插件。这不是权限没导对,而是认证层不匹配。
临时解法(针对已有用户):
- 在目标库执行
ALTER USER 'username'@'host' IDENTIFIED WITH mysql_native_password BY 'password'; - 不要改全局
default_authentication_plugin,否则新建的管理账号也会被降级,削弱安全性 - 验证改完后是否生效:
SELECT user, host, plugin FROM mysql.user WHERE user = 'username';
更稳妥的做法是在导出前就筛查:SELECT user, host, plugin FROM mysql.user;,把需要兼容的用户单独标记,批量处理。
skip_name_resolve 关闭会导致权限匹配失效
权限规则里写的是 'user'@'192.168.1.%',但实际连接时如果目标库没开 skip_name_resolve(默认开启),MySQL 会做反向 DNS 查询,把客户端 IP 解析成域名,结果匹配到 'user'@'%.example.com' 这类规则——而这条规则可能根本不存在,于是拒绝连接。
解决方法很简单:
- 确认目标库配置:检查
my.cnf是否含skip_name_resolve=ON - 若没有,加上并重启;若已有,检查 DNS 是否能正向/反向解析一致
- 线上环境建议统一用 IP 段授权(如
'user'@'10.0.0.%'),避免依赖 DNS
这个点容易被忽略,因为权限语句本身没错,错在运行时解析行为变了——查日志会看到 Access denied for user ... using password: YES,但用户名密码完全正确。











