不能用mysqldump --all-databases迁移用户,因5.7的mysql.user含Password字段而8.0改用authentication_string,且plugin等字段缺失,硬导入会报ERROR 3554或静默失败;正确做法是跳过系统库,仅导出GRANT逻辑并适配mysql_native_password插件。

直接导入 mysql 系统库会失败,8.0 的权限表结构(如 user 表的 password 字段已改为 authentication_string)、认证插件默认值、sql_mode 严格性都不兼容。必须跳过系统库导出,再手动重建用户。
为什么 mysqldump --all-databases 不能用于迁移用户
导出时会把 5.7 的 mysql.user 表结构和数据原样写入 SQL 文件,而 8.0 启动后拒绝加载该定义:字段名不匹配、plugin 字段缺失、password 列类型被忽略。导入时通常报错 ERROR 3554 (HY000): Access to system table 'mysql.user' is rejected 或静默跳过权限语句,导致所有账号丢失或无法登录。
正确导出用户权限的三个操作要点
只导出权限逻辑,不碰系统表物理结构:
- 用
mysqldump加--skip-triggers --skip-routines --no-create-info参数,仅导出GRANT语句:mysqldump -u root -p --no-data --skip-triggers --skip-routines mysql user db event proc proxies_priv > grants.sql - 手动过滤掉
CREATE USER中含caching_sha2_password的行(5.7 不生成该插件,但某些 dump 工具会硬编码),替换成mysql_native_password - 确保导出的
GRANT语句末尾带IDENTIFIED WITH mysql_native_password(不是BY密码明文),否则 8.0 会因插件不匹配拒绝创建
在 MySQL 8.0 中安全导入权限的步骤
导入前必须关闭系统表保护,且避免触发自动升级逻辑:
- 启动 8.0 实例时加参数
--skip-grant-tables --shared-memory(仅临时),或先以普通模式启动后执行FLUSH PRIVILEGES前停掉复制与应用连接 - 导入前删掉所有旧用户:
DELETE FROM mysql.user WHERE User != 'root'; FLUSH PRIVILEGES;(注意:别删 root,否则可能锁死) - 用
source grants.sql执行,若报ERROR 1396 (HY000)(用户已存在),说明部分CREATE USER重复,加IF NOT EXISTS手动补全或分步执行 - 导入后立即运行
ALTER USER 'xxx'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx';强制统一插件,再FLUSH PRIVILEGES;
最容易被忽略的两个兼容性雷区
一是客户端驱动不支持新认证协议:PyMySQL SHOW GRANTS 输出格式变了——8.0 默认不显示 IDENTIFIED WITH 子句,得加 FOR 显式指定用户才能看到完整授权语句,排查时容易误判权限缺失。


















