mysqlpump默认不生成create user语句,仅导出grant权限,需加--users及--include-databases=mysql等参数组合才能完整导出用户与权限;跨版本迁移时需注意密码插件兼容性,并执行flush privileges生效。

mysqlpump 导出用户权限时为什么没生成 CREATE USER 语句
默认情况下 mysqlpump 不导出用户账号定义,只导出权限(GRANT),而目标实例若不存在对应用户,执行 GRANT 就会报错:ERROR 1133 (42000): Can't find any matching row in the user table。
必须显式启用账号导出功能:
- 加
--users参数:仅导出mysql.user表中用户记录(含密码哈希),但不导出权限 - 加
--include-databases=mysql+--skip-definer+--add-drop-user:才能同时导出CREATE USER和GRANT - 实际最稳妥组合是:
mysqlpump --users --include-databases=mysql --skip-definer --add-drop-user --skip-triggers --skip-events
导出的权限 SQL 在新实例执行时报错 ERROR 1045 或 ERROR 1227
常见于用普通账号导出后、试图用非 root 账号在新实例导入 —— CREATE USER 和部分 GRANT 需要 CREATE USER、INSERT 或 GRANT OPTION 权限。
务必确认导入时连接账号具备:
-
CREATE USER权限(不是CREATE) -
INSERT权限 onmysql.*(因写入mysql.user等系统表) -
GRANT OPTION(否则无法还原带WITH GRANT OPTION的授权) - 推荐直接用
root@localhost执行导入,避免权限链路绕弯
MySQL 5.7 和 8.0 之间迁移权限时密码字段不兼容
MySQL 8.0 默认用 caching_sha2_password 插件,而 5.7 是 mysql_native_password;mysqlpump 导出的 CREATE USER 语句会原样保留 authentication_string 和插件名,直接导入 5.7 会失败:ERROR 1064 (42000): You have an error in your SQL syntax。
解决方法分场景:
- 从 8.0 → 8.0:无需处理,保持原样
- 从 8.0 → 5.7:导出后手动替换所有
IDENTIFIED WITH caching_sha2_password AS 'xxx'为IDENTIFIED BY PASSWORD 'xxx',并确保目标实例已启用old_passwords=0(5.7.5+ 默认支持) - 从 5.7 → 8.0:导入后建议运行
ALTER USER ... IDENTIFIED WITH caching_sha2_password主动升级,否则客户端可能连不上
导入后用户能登录但查不到库/表,或权限不生效
这不是导出问题,而是 MySQL 权限缓存机制导致的:导入 mysql.user 后,服务端不会自动重载权限表。
必须显式刷新:
- 执行
FLUSH PRIVILEGES;(最直接) - 或重启 mysqld(不推荐,影响业务)
- 注意:如果导入脚本末尾没加
FLUSH PRIVILEGES;,即使 SQL 看似执行成功,权限也未生效 - 可快速验证:
SELECT User,Host,authentication_string FROM mysql.user WHERE User='xxx';看记录是否存在;再用该用户连接后执行SHOW GRANTS;
权限迁移这事,核心不在“导得出来”,而在“导得准、改得对、刷得及时”。尤其跨版本时,authentication_string 字段和插件名稍不留意就卡住整个上线流程。











