mysql 8.0.16起mysql_upgrade已被彻底移除,升级由mysqld启动时自动执行--upgrade选项(默认auto),手动运行该命令将报错或引发元数据冲突;系统表必须为innodb引擎,且plugin字段需匹配客户端认证插件(如mysql_native_password)。

mysql_upgrade在MySQL 8.0中已彻底失效,别再运行它
MySQL 8.0.16起,mysql_upgrade 已被官方移除。执行该命令只会报 command not found,或在旧残留脚本里触发元数据冲突,导致mysql.user字段错乱、performance_schema视图不可用。升级后若发现 SHOW GRANTS 返回空、SELECT * FROM mysql.user 报“Unknown column 'password_last_changed'”之类错误,说明系统表结构未适配——这不是工具没跑,而是它根本不存在了。
真正生效的机制是:MySQL服务器自身在首次用新二进制启动旧数据目录时,自动执行内部升级逻辑。这个过程不可跳过,也无法用客户端工具替代。
升级后连不上、提示MyISAM不支持系统表,本质是引擎残留
错误日志出现 [MY-010929] Storage engine 'MyISAM' does not support system tables. [mysql.user],说明升级前的mysql库中仍有 MyISAM 表(如mysql.db、mysql.columns_priv等),而 MySQL 8.0 要求所有系统表必须为 InnoDB 引擎。
这不是配置问题,也不是权限问题,是数据目录未被正确迁移或清理。常见诱因包括:
- 直接覆盖安装二进制,但没清空或替换旧
/var/lib/mysql/mysql/目录 - 升级过程中使用
--skip-grant-tables启动后执行了DROP TABLE或TRUNCATE操作 - 从低版本(如5.7)跨大版本升级,未按官方路径先升到中间版(如5.7→8.0.22→8.0.44)
用--upgrade=FORCE强制触发系统表升级
当 MySQL 启动失败或卡在“系统表结构不匹配”阶段时,可手动控制升级行为。关键不是重装或初始化,而是让服务以升级模式启动一次:
- 确认
mysqld进程已完全退出:ps aux | grep mysqld无残留 - 临时注释掉配置文件中的
innodb_force_recovery(否则升级会跳过) - 执行启动命令:
mysqld --user=mysql --datadir=/var/lib/mysql --upgrade=FORCE - 观察错误日志,成功时会出现类似
Upgrading system tables...和Finished upgrading system tables的日志行 - 正常启动服务:
systemctl start mysql,不再加--upgrade参数
注意:--upgrade=FORCE不会重建用户、角色或GTID状态,只修正系统表结构和字段;若此前已用--initialize-insecure覆盖过mysql目录,则此步无效——因为原表已丢失。
修复后仍无法登录,重点检查plugin字段是否为mysql_native_password
即使mysql.user表存在且字段齐全,登录仍被拒绝,大概率是plugin字段值异常。MySQL 8.0 默认改用caching_sha2_password,但老客户端或某些连接池不兼容。
此时需在安全模式下修正:
- 停服务,启动时加
--skip-grant-tables --skip-networking - 连接后执行:
UPDATE mysql.user SET plugin='mysql_native_password' WHERE user='root' AND host='localhost'; - 再执行:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_pwd'; FLUSH PRIVILEGES; - 重启服务(务必去掉
--skip-grant-tables)
这一步常被忽略——系统表修好了,但认证插件不匹配,照样连不上。尤其在混合环境(Java应用+旧PHP驱动)中,plugin字段就是登录成败的临界点。











