mysqlcheck --check-upgrade 是升级前必须执行的硬性检查,会真实触发8.0元数据校验逻辑,识别enum默认值、text default、保留字冲突等不兼容问题,需停写且仅读模式下运行。

用 mysqlcheck --check-upgrade 验证表结构是否满足8.0元数据要求
这个命令不是可选项,是升级前必须跑的硬性检查。它会真实触发 MySQL 8.0 的元数据校验逻辑,而不仅仅是语法扫描——比如 ENUM 默认值为空字符串、TEXT 字段写了 DEFAULT ''、列名撞上 rank 这类保留字,都会被识别为不兼容。
执行前必须停写(只读),否则可能漏检或误报:
-
mysqlcheck -u root -p --all-databases --check-upgrade是基础命令,--check-upgrade参数缺一不可,其他参数如--fix-db-names只是附带功能 - 遇到
The table does not comply with the current version of MySQL错误,说明该表在 8.0 启动时会被跳过或拒绝加载,常见于 MyISAM 分区表、孤立.frm文件 - 对含
JSON字段的表,mysqlcheck不报错也不代表安全:手动补查SELECT * FROM tbl WHERE json_valid(col) = 0更稳妥
用 util.checkForServerUpgrade() 扫描跨版本语义变更
mysqlcheck 看不到的问题,util.checkForServerUpgrade() 才能暴露。它专为 5.7→8.0 设计,会检查字符集、认证插件、SQL mode、保留关键字等 20+ 项语义级不兼容点。
必须严格满足三个前提,否则结果无效:
- MySQL Shell 版本必须 ≥ 目标 MySQL 8.0 版本(例如升到
8.0.42,就得用mysql-shell-8.0.42) - 连接必须走本地 socket:
./mysqlsh -uroot -p -S /tmp/mysql.sock -e "util.checkForServerUpgrade()",避免网络或权限干扰 - 执行用户需有
SUPER权限和全库SELECT权限(root最稳)
报告中 ERROR 级条目必须清零才能继续,例如:
-
Usage of utf8mb3 charset→ 全量执行ALTER DATABASE db_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci -
Column name 'rank' is a reserved keyword→ 改列名,不能靠引号绕过 -
caching_sha2_password plugin not supported by client→ 检查 JDBC 驱动版本是否 ≥8.0.13,否则提前升级或切回mysql_native_password
验证 sql_mode 和隐式行为变化
5.7 中允许但 8.0 默认禁用的行为,往往在升级后第一笔业务 SQL 就暴露。重点盯住三类配置项:
-
NO_AUTO_CREATE_USER:若仍显式写在sql_mode里,8.0 启动直接失败,报错类似Unknown system variable 'sql_mode';必须从my.cnf中删掉整段 -
STRICT_TRANS_TABLES是否启用:未启用时,插入超长字符串会被截断而不报错;升级后若开启严格模式,应用可能突然收到Data too long报错 - 隐式类型转换引发的锁范围扩大:比如
WHERE mobile = 13800138000(字段为VARCHAR),8.0 更倾向放弃索引走全表扫描,导致锁升级;建议在测试环境用EXPLAIN对比执行计划
升级后第一分钟必须跑的四条验证 SQL
进程起来了 ≠ 数据库就绪。以下命令缺一不可,漏掉任一都可能埋下半夜告警:
-
SELECT VERSION(), @@sql_mode;—— 确认版本是8.0.x,且ONLY_FULL_GROUP_BY在sql_mode列表中(这是 8.0 默认行为) -
SHOW VARIABLES LIKE 'default_authentication_plugin';—— 若返回caching_sha2_password,确认所有客户端驱动已适配;否则应设为mysql_native_password -
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE = 'MyISAM';—— 结果必须为空,8.0 已移除 MyISAM 支持 -
SELECT COUNT(*) FROM performance_schema.data_locks;—— 非零表示当前有活跃锁,结合业务流量观察是否异常增多
最易被忽略的是锁行为变化:它不会在启动时报错,而是在高并发场景下才触发死锁或长事务阻塞。必须在业务低峰期压测关键路径,并持续观察 performance_schema.data_locks 和 SHOW ENGINE INNODB STATUS\G 输出。











