mysql 8.0权限模型重构导致直接导入5.7的mysql.user表失败,因password字段改为authentication_string、引擎强制innodb且新增字段,启动校验崩溃;必须提前适配插件与驱动,升级后立即重置root认证方式并验证。

不能直接导出导入 mysql 库,也不能依赖 mysql_upgrade 重建权限表——8.0 的权限模型已重构,字段名、存储逻辑、引擎要求全变了。
为什么 mysqldump 导入 mysql.user 会失败
5.7 的 mysql.user 表含 password 字段、MyISAM 引擎、大量空值默认;8.0 中该字段已改为 authentication_string,强制 InnoDB,且新增 password_reuse_history 等字段。一旦把旧数据导入,mysqld 启动时校验失败,直接崩溃或卡在 “Starting MySQL”。
- 执行
mysqldump --all-databases后若未手动删掉所有USE mysql和INSERT INTO mysql.行,导入即埋雷 -
mysqlcheck --check-upgrade不检查权限表结构兼容性,它根本看不到这个风险 - 即使启动成功,用老客户端连时抛
Client does not support authentication protocol,本质是认证插件不匹配,不是密码错了
升级前必须清理的权限相关残留
权限迁移不是“复制粘贴”,而是“重置+适配”。以下动作必须在 5.7 实例运行时完成:
- 查出所有用
caching_sha2_password插件的用户:SELECT user, host, plugin FROM mysql.user WHERE plugin = 'caching_sha2_password';—— 若应用尚未升级驱动(如mysql-connector-java ),这些账号将无法登录 - 确认无 MyISAM 权限表:
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'mysql' AND ENGINE = 'MyISAM';—— 8.0 启动时拒绝加载任何 MyISAM 系统表,哪怕只是mysql.plugin - 禁用
skip-grant-tables模式后,确保 root 有SUPER权限:否则util.checkForServerUpgrade()会因权限不足跳过部分检查
升级后重置权限的最小安全操作集
8.0 启动成功 ≠ 权限可用。必须立刻执行四条语句验证并加固:
- 设回兼容插件:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_secure_password'; - 刷新权限:
FLUSH PRIVILEGES; - 验证插件生效:
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';—— 结果中plugin必须为mysql_native_password - 检查是否启用新权限模型:
SELECT @@default_authentication_plugin;—— 输出应与上一条一致,且不能是空或caching_sha2_password
漏掉任意一条,第二天 PHP/Java 连接池就会批量报错,而日志里只显示 “Access denied”,根本看不出是插件不匹配。
真正平滑的关键:权限迁移不发生在升级时刻
权限不是从 5.7 “迁”到 8.0,而是在升级窗口期外就完成适配。最稳妥路径是:
- 提前一周,在测试环境用
util.checkForServerUpgrade()扫出所有用户级 ERROR(如caching_sha2_password plugin not supported by client),然后同步更新应用连接串或驱动版本 - 升级前用
SELECT CONCAT('CREATE USER ''',user,'''@''',host,''' IDENTIFIED WITH ',plugin,' AS ''',authentication_string,''';') FROM mysql.user;生成 8.0 兼容的建用户语句,但不执行——仅用于预案 - 升级后第一分钟内只重置 root 和监控账号,业务账号按需分批重置,避免连接风暴
把权限当成配置项而非数据来管理,才能避开那个最隐蔽的坑:你以为改了密码,其实只是换了认证方式,而客户端根本没准备好。











