不能把旧版 mysql 库直接导入 8.0+ 实例,必须用兼容方式重建权限元数据;跨大版本迁移后账号无法登录,90% 是因为 mysql.user 表结构不匹配(如缺 password_last_changed 字段、plugin 值非法或 authentication_string 格式错),并非密码错误。

直接结论:不能把旧版 mysql 库直接导入 8.0+ 实例,必须用兼容方式重建权限元数据。跨大版本迁移后账号无法登录,90% 是因为 mysql.user 表结构不匹配(比如缺 password_last_changed 字段、plugin 值非法、或 authentication_string 格式错),不是密码错了。
为什么 mysqldump --all-databases 导出的 mysql 库在新实例上会失败
旧版导出的 mysql 库含 5.7 的表结构和字段(如 Password 列),而 MySQL 8.0+ 已移除该列、改用 authentication_string,且新增了 password_historyaccount_locked 等字段。硬导入会触发:
ERROR 1067 (42000): Invalid default value for 'password_last_changed'- 后续启动失败,或
SELECT USER();返回空 - 即使启动成功,所有用户登录都报
Access denied,连root@localhost都失效
正确做法:跳过旧权限表,用官方初始化重建结构
前提是原业务库(/var/lib/mysql/your_db/)文件完好,只丢权限元数据。操作前停掉 MySQL:
- 执行
mysqld --initialize-insecure --datadir=/var/lib/mysql --user=mysql(路径按实际改) - 它会生成全新
mysql系统库,含 8.0 正确字段、索引、默认 root 账户(空密码) - 启动 mysqld:
systemctl start mysqld(不要加--skip-grant-tables) - 立刻用空密码进:
mysql -u root -p(回车即可),然后重设密码:ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
如何把老用户权限安全迁移到新结构
不能 INSERT 旧数据,但可以用逻辑授权语句还原。从旧库导出可重放的 GRANT:
- 在旧实例(5.7 或兼容环境)运行:
pt-show-grants --user=root --password=xxx --no-header > grants.sql(需安装 Percona Toolkit) - 或手动导出:
mysqldump -u root -p --skip-triggers --compact mysql user db tables_priv columns_priv procs_priv > priv_backup.sql - 清理 SQL 中的
PASSWORD('xxx')(8.0 不认)、NO_AUTO_CREATE_USER模式等废弃语法 - 导入到新实例:
mysql -u root -p mysql ,再执行 <code>FLUSH PRIVILEGES;
最后检查 SELECT User, Host, plugin, authentication_string FROM mysql.user; —— 如果 plugin 是 caching_sha2_password 但客户端老旧,记得临时切回:ALTER USER 'xxx'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';。别漏掉 FLUSH PRIVILEGES;,这个命令在 8.0+ 仍有效,且是权限真正加载进内存的唯一信号。











