必须用util.checkForServerUpgrade(),它是Oracle官方唯一推荐的5.7→8.0升级前检查工具,可全面扫描字符集、认证插件、保留关键字、SQL模式等21类核心兼容问题;mysqlcheck仅校验表结构,无法识别跨版本语义变更。

必须用 util.checkForServerUpgrade(),其他工具只能辅助,它才是唯一能覆盖21类核心兼容问题的官方手段。
为什么非得用 MySQL Shell 而不是 mysqlcheck 或手动查文档
mysqlcheck 只能扫出部分语法弃用(比如旧认证插件),但漏掉大量隐性风险:旧时间类型格式、保留字冲突、系统表字段变更、配置项默认值漂移。而人工对照 Release Notes 容易遗漏行为级变化——比如 GROUP BY 隐式排序取消,SQL 本身合法,但结果错得无声无息。只有 util.checkForServerUpgrade() 会实际加载你的表结构、触发器定义、用户权限和配置文件,做语义级分析。
- 它依赖当前连接的 MySQL 实例上下文,不是静态扫描 SQL 文本
- 会读取
my.cnf并比对目标版本中已移除或默认值变更的参数 - 输出带严重等级(
Error/Warning/Notice),每条都附带修复建议
util.checkForServerUpgrade() 的正确调用方式
别在命令行直接拼接参数跑,容易丢配置路径或权限上下文。推荐分步执行:
- 先启动交互式 shell:
mysqlsh --uri root@localhost:3306(确保账户有SUPER权限) - 再执行检查,显式传入配置路径和目标版本:
util.checkForServerUpgrade({'targetVersion': '8.0.34', 'configPath': '/etc/my.cnf'}) - 如果没指定
configPath,工具不会检查配置兼容性,这是常见疏漏 - 结果是 JSON 对象,用
print(check_result)查看,别只看终端最后一屏
看到 Error 级报错时最该盯紧的三类问题
升级失败基本就卡在这三类 Error 上,修复不彻底会导致 in-place 升级中途退出:
-
oldTemporalCheck:报错含"Usage of old temporal type",说明存在 MySQL 5.5 二进制时间格式的列。必须对每张表执行ALTER TABLE 表名 FORCE,不能只改字符集 -
schemaInconsistencyCheck:提示"Schema inconsistencies",通常是 .ibd 文件被手动删过。用SELECT * FROM information_schema.innodb_sys_tables找出 orphan 表,再决定是重建还是清理数据字典 - 保留字冲突:报错含
"object name conflict"且列名是rank、window、system等,必须重命名列,ALTER COLUMN 不行,得用CHANGE COLUMN或导出重建
Warning 和 Notice 级问题常被忽略的后果
这类问题不阻断升级,但上线后才暴露:
-
Warning中的sql_mode变更(如ONLY_FULL_GROUP_BY启用):应用里没写ORDER BY的分页查询,结果顺序随机,前端分页错乱 -
Notice提到的caching_sha2_password认证:Java 应用若用mysql-connector-java < 8.0.16,连接池初始化就失败,错误日志只显示Access denied,不提插件问题 -
Notice关于utf8mb4_0900_ai_ci排序规则:老表用utf8mb4_general_ci,JOIN 时隐式转换导致索引失效,慢查询突增
真正麻烦的不是 Error 报错,而是 Warning 和 Notice 里那些“升级成功但业务逻辑悄悄变了”的点——它们不会让你升级失败,但会让你在凌晨三点排查一个本不该存在的分页 bug。


















