mysql 5.7 升级 8.0 时因 user 表结构变更(password 移除、plugin 非空、强制 innodb)导致权限导入失败,需用 mysqlpump 或过滤 mysqldump 导出语义化 grant 语句,并统一认证插件为 mysql_native_password。

mysql.user 表结构变更导致权限导入直接失败
MySQL 5.7 的 mysql.user 表有 password 字段、plugin 字段为可选,引擎可以是 MyISAM;而 8.0 强制 InnoDB,password 字段已移除,改用 authentication_string,且 plugin 变为非空字段。直接 mysqldump --databases mysql 导出再导入,会卡在第 12 张表(通常是 user),报错类似 ERROR 1067 (42000) at line XXX: Invalid default value for 'plugin'。
用 mysqldump + 过滤 + 手动重建用户是最可控的方式
不要试图导出整个 mysql 库,只提取用户和权限逻辑,绕过物理结构差异:
- 从 5.7 执行:
mysqldump -u root -p --no-create-info --skip-extended-insert mysql user db tables_priv columns_priv procs_priv proxies_priv > users_and_grants.sql - 用 sed 或编辑器删掉所有含
INSERT INTO `mysql`.`user` VALUES的行中password字段对应值(第 50 列左右),替换为''或留空;同时确保plugin字段值是'mysql_native_password'(不是caching_sha2_password) - 在 8.0 中先清空旧权限状态:
DELETE FROM mysql.user WHERE User != 'root'; FLUSH PRIVILEGES;(注意保留 root,避免锁死) - 导入前,在 8.0 配置里加
default_authentication_plugin=mysql_native_password,否则新插入的用户仍会用新插件,PHP/宝塔等老客户端连不上
用 mysqlpump 或 pt-show-grants 做语义级导出更安全
mysqlpump(MySQL 5.7.8+ 自带)比 mysqldump 更懂权限对象,能生成 CREATE USER + GRANT 语句,不依赖表结构:
- 在 5.7 上运行:
mysqlpump --exclude-databases=% --users --grants --skip-definer > grants.sql - 生成的文件不含
INSERT,全是可读的CREATE USER 'xxx'@'%' IDENTIFIED WITH mysql_native_password AS '***';类语句 - 导入前确认目标 8.0 已设
default_authentication_plugin=mysql_native_password;若必须用caching_sha2_password,则需提前升级 JDBC 驱动并加连接参数?serverTimezone=UTC&allowPublicKeyRetrieval=true
宝塔或一键升级后 root 密码失效的紧急修复
宝塔点“升级 MySQL”后常见现象:服务起来但 PHP 连不上、phpMyAdmin 报错 Client does not support authentication protocol。这不是密码错了,而是 root 用户被自动转成 caching_sha2_password 插件:
- 用 socket 登录:
mysql -S /tmp/mysql.sock -u root -p - 执行:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES; - 如果连 socket 都进不去,就临时在
/etc/my.cnf的[mysqld]段加skip-grant-tables启动,再进库重置,完事后务必删掉这行并重启











