MySQL 8.0+升级后系统表结构不匹配问题本质是数据字典未同步,因mysql_upgrade已被移除,必须依赖mysqld首次启动时自动升级(AUTO模式),手动执行该命令将报错或引发元数据冲突;若失败需检查错误日志、确认InnoDB引擎及plugin字段一致性,并确保启动时未启用innodb_force_recovery。

这个问题本质是系统表结构没对齐,不是数据丢了,也不是权限或配置错了——mysql_upgrade 没跑或跑失败了,或者升级后服务重启时没完成数据字典同步。
为什么 mysql_upgrade 必须手动执行?
MySQL 8.0+ 不再自动触发升级逻辑。哪怕你用 mysqld --upgrade 启动,也只做最小兼容检查,不会重建系统表或刷新数据字典。报错 Table metadata is out of sync 通常出现在 INFORMATION_SCHEMA 或 mysql 库下的表(比如 user、columns_priv)结构与当前版本不匹配。
- 必须在 MySQL 服务运行状态下,用对应版本的
mysql_upgrade工具执行,不能用旧版客户端调用新版服务 - 执行前确保
mysqld是目标版本(如 8.0.33),且启动用户有mysql系统库的写权限 - 命令示例:
mysql_upgrade -u root -p --force;加--force可跳过“已升级”标记检查,强制重刷 - 执行完会提示
Finished upgrading MySQL tables,此时需重启mysqld才生效
mysql_upgrade 执行失败的常见原因
失败不等于退出码非 0,有时它静默跳过某些表——尤其当 mysql 库里存在自定义字段、触发器或视图依赖旧结构时。
-
ERROR 1267 (HY000): Illegal mix of collations:说明字符集/排序规则冲突,常见于从 5.7 升级到 8.0 时utf8mb4_0900_as_cs替代了utf8mb4_general_ci;需先用ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_as_cs;统一库级设置 - 找不到
mysql.plugin表:这是典型系统表缺失,mysql_upgrade会尝试重建,但如果datadir下的mysql目录被手动改过权限或损坏,就会卡住;此时应停服务,备份原mysql/目录,再用同版本mysqld --initialize-insecure生成新系统库,最后导入用户权限 - 执行后仍报错:检查
/var/log/mysql/error.log,重点搜Failed to upgrade和Unknown table,这些行会指出具体哪张表没刷成功
绕过 mysql_upgrade 的临时方案(仅限紧急读取)
如果服务起不来、mysql_upgrade 死循环或磁盘空间不足,可临时启用 innodb_force_recovery 强制加载,但仅限导出数据,不可写入。
- 在
my.cnf的[mysqld]段下加:innodb_force_recovery = 1(值从 1 到 6,优先试 1) - 启动后立刻用
mysqldump --all-databases --skip-lock-tables > full_backup.sql导出 - 导出完成后必须删掉
innodb_force_recovery并重启,否则任何 DML 都会被拒绝 - 注意:
innodb_force_recovery不修复元数据,只是让引擎忽略部分一致性检查,所以SHOW CREATE TABLE可能返回空或错误结构
真正麻烦的不是升级动作本身,而是升级后没人去查 information_schema.INNODB_TRX 和 performance_schema.metadata_locks ——很多“表无法访问”其实是长事务挂着 MDL 锁,和元数据同步无关,但错误日志里混着两条线索,容易误判。


















