必须用util.checkforserverupgrade(),因mysqlcheck仅校验表结构完整性与物理损坏,完全不感知mysql 8.0引入的utf8mb3弃用、caching_sha2_password认证插件、rank等保留字冲突及only_full_group_by等sql模式变更。

必须用 util.checkForServerUpgrade(),别碰 mysqlcheck 做兼容性判断——它根本不会报 caching_sha2_password 认证失败、rank 列名冲突或 ONLY_FULL_GROUP_BY 导致的 SQL 报错。
为什么 mysqlcheck 不能代替升级兼容性检查
mysqlcheck 只校验表文件是否损坏、索引页是否断裂,属于存储引擎层的“身体体检”。它完全不解析 SQL 语义,也不比对版本间行为差异。
- 遇到
GROUP BY查询在 8.0 下因sql_mode变严而报错?mysqlcheck一声不吭 - 列名叫
window或system,升级后所有SELECT window FROM t全挂?mysqlcheck视而不见 - 客户端用老驱动连不上,卡在
Authentication plugin 'caching_sha2_password' cannot be loaded?mysqlcheck不查认证链 - 表默认字符集还是
utf8(即utf8mb3),8.0 虽兼容但已警告废弃?mysqlcheck不扫描字符集定义
怎么运行 util.checkForServerUpgrade() 才有效
这个函数是 MySQL Shell 8.0+ 自带的专用检查器,必须用 8.0 版本的 mysqlsh 连接 5.7 实例执行,不能反向操作。
- 确保已安装 MySQL Shell 8.0.33 或更高版本(低版本可能缺关键检测项)
- 连接方式要带完整 URI:
mysqlsh --uri root@localhost:3306,不能只用 socket 或跳过端口 - 目标版本必须显式指定:
util.checkForServerUpgrade({targetVersion: '8.0.41'}),写成'8.0'会用默认值,可能漏检 - 输出格式建议用
JSON:outputFormat: 'JSON',方便脚本解析;终端查看可用默认文本模式 - 若实例使用非标准配置文件,需通过
--config-path=/etc/my_57.cnf显式传入,否则可能读错sql_mode等设置
看到哪些输出必须处理才能升级
检查结果里真正拦路的是 ERROR 和 WARNING 级别条目,summary 段末的 overallStatus 必须为 OK。重点关注这几类:
-
Usage of utf8mb3 charset:所有 schema、table、column 的CHARACTER SET utf8都得改成utf8mb4,包括mysql系统库里的表(如mysql.plugin) -
Names conflicting with new reserved keywords:像window、rank、group这类列名,应用 SQL 中必须加反引号,比如SELECT `window` FROM t -
Usage of old temporal type:说明存在 5.5 之前创建的旧时间类型表,需在 5.7 上先执行ALTER TABLE t FORCE触发重建 -
InnoDB Cluster member且isInnoDBCluster: true:不能直接升级,得先停集群、逐节点操作,否则元数据同步中断 -
NO_AUTO_CREATE_USER出现在sql_mode里:8.0 已移除该模式,必须从全局和会话级中清除
检查完之后最容易被跳过的一步
很多人跑完 util.checkForServerUpgrade() 看到 OK 就去升级,忘了 mysqlcheck -u root -p --all-databases --check --extended 必须同步做——它不查兼容性,但能发现 MyISAM 表损坏、InnoDB 页校验失败等物理问题。这类问题在 5.7 下可能只是慢一点,但 8.0 启动时会直接拒绝加载损坏表,导致实例无法启动。
尤其是 mysql.plugin 表如果还是 MyISAM 引擎,升级命令 mysqld --upgrade=FORCE 会卡在 Can't find file: './mysql/plugin.frm',必须提前在 5.7 下执行 ALTER TABLE mysql.plugin ENGINE=InnoDB。











