mysqlcheck不能发现mysql 5.7→8.0兼容性隐患,它仅检查表结构物理损坏;必须用mysqlsh的util.checkforserverupgrade()扫描字符集、保留字、认证插件等语义级问题。

mysqlcheck 不能发现 MySQL 5.7 → 8.0 的版本兼容性隐患,它根本不是为这个目的设计的。
它只检查表结构层面的物理损坏,比如索引断裂、页校验失败、MyISAM 表头损坏等。你用它跑完“一切正常”,不代表升级后 SQL 不报错、连接不中断、排序不乱码。
真正该关心的兼容性问题——sql_mode 变更、caching_sha2_password 认证插件、列名撞 rank 这类保留字、utf8 字符集残留——mysqlcheck 全部视而不见。
mysqlcheck 的真实用途:修表,不是查兼容性
- 它本质是
CHECK TABLE、REPAIR TABLE等语句的封装,只和存储引擎的磁盘数据布局打交道 - 输出里出现
error或warning(例如MyTable is marked as crashed),说明你得先修复再升级,否则 8.0 启动直接失败 - 对大表加
--extended是必要的,但耗时;不加可能漏掉深层页损坏 - 系统库可跳过:
--ignore-database=mysql --ignore-database=information_schema,但sys库建议保留——它在 8.0 中是视图集合,结构变化大,损坏会影响后续诊断
升级前必须换工具:用 util.checkForServerUpgrade()
这才是 Oracle 官方唯一推荐的兼容性扫描器,能覆盖你真正会踩的坑:
- 扫出所有使用
utf8(即utf8mb3)的地方,包括库、表、列默认字符集 - 标记
window、rank、first_value这类在 8.0 成为保留字的列名或别名 - 检测
NO_AUTO_CREATE_USER这种已被移除的sql_mode - 提示
caching_sha2_password插件不被老客户端支持,需确认驱动版本(如mysql-connector-java ≥ 8.0.13) - 报告里
overallStatus不是OK就不能继续升级
典型命令:
mysqlsh -uroot -p -S /tmp/mysql.sock -e "util.checkForServerUpgrade({targetVersion: '8.0.41', outputFormat: 'JSON'})"
为什么有人误信 mysqlcheck 能查兼容性?
- 它名字带 “check”,容易望文生义
- 文档里写 “--check-upgrade”,但这个参数只是让
mysqlcheck在检查时顺便提醒某些 5.7 特有行为(如 MyISAM 表),不涉及 8.0 语义 - 有些运维把“表没坏”等同于“能升级”,结果升级后第一句
SELECT * FROM user ORDER BY rank就报语法错误
真正要保平滑,mysqlcheck 只负责“别让损坏的表拖垮启动”,其余所有逻辑层风险,必须靠 util.checkForServerUpgrade() + 人工核对 + 测试环境回放真实 SQL。漏掉任何一层,上线就可能卡在登录、查询或权限校验上。











