mysqlcheck 不用于 mysql 5.7→8.0 兼容性检查,仅校验存储引擎物理结构一致性,不分析 sql 语法、sql_mode、字符集或保留字冲突;应使用 pt-upgrade 并人工核验 sql_mode、排序规则和保留字。

直接说结论:mysqlcheck 不是用来做 MySQL 5.7 → 8.0 兼容性检查的工具,它既不分析 SQL 语法差异,也不校验 sql_mode、字符集隐式转换或保留字冲突。强行用它“检查兼容性”,反而会漏掉真正致命的问题。
mysqlcheck 的真实用途和局限
mysqlcheck 是一个表级维护工具,本质是封装了 CHECK TABLE、REPAIR TABLE、ANALYZE TABLE 和 OPTIMIZE TABLE。它只干一件事:验证和修复存储引擎层面的物理结构一致性(比如 InnoDB 页损坏、索引断裂)。它完全不解析 SQL 语义,也不关心你执行的 SELECT 在 8.0 下是否报错。
- 它不会告诉你
GROUP BY查询在 STRICT 模式下是否因ONLY_FULL_GROUP_BY失败 - 它不会发现
rank或first_value作为列名在 8.0 中触发语法错误 - 它对
utf8mb4_general_ci和utf8mb4_0900_ai_ci混用导致的Illegal mix of collations错误毫无感知 - 它不检查客户端连接时因
caching_sha2_password认证插件引发的连接拒绝
真正该用什么检查兼容性?
必须换工具——pt-upgrade(Percona Toolkit)才是专为跨版本 SQL 兼容性设计的方案。它能实打实地把你的业务 SQL(慢日志、general log、binlog 解析结果)在两个实例上并行执行,对比结果一致性。
- 支持
--type=slowlog直接喂入生产慢查询日志,覆盖高频路径 - 用
--query-time-threshold标出 8.0 中变慢超过 2 倍的语句,提前预警性能回退 - 自动捕获
SQLSTATE[42000]类语法错误,并定位到具体哪一行 SQL - 当两个实例都报错但错误码不同(如 5.7 是
1055,8.0 是3028),它会明确标出 “SQL errors” 差异 - 注意:需确保测试库数据量、索引状态与生产一致,否则
Query time对比无意义
升级前必须手动验证的三类关键点
工具只能覆盖一部分,以下必须人工核对,否则上线即故障:
-
sql_mode 变更:检查所有应用启动脚本、ORM 配置、连接池初始化 SQL。若含
NO_AUTO_CREATE_USER,必须删掉;若含STRICT_TRANS_TABLES但业务写入 NULL 到 NOT NULL 字段,要补默认值或改逻辑 -
字符集/排序规则混用:运行
SELECT table_schema, table_name, column_name, collation_name FROM INFORMATION_SCHEMA.COLUMNS WHERE collation_name NOT IN ('utf8mb4_0900_ai_ci', 'utf8mb4_unicode_ci');找出非统一排序规则的字段,尤其关注 JOIN / WHERE / ORDER BY 涉及的列 -
保留字冲突:MySQL 8.0 新增
RANK、FIRST_VALUE、LAST_VALUE等窗口函数名。检查建表语句和列名,ALTER TABLE t1 CHANGE rank rank_old VARCHAR(32);这类重命名无法自动完成
最易被忽略的是:升级后首次执行 mysqld --upgrade=FORCE 时,如果系统表权限不全(比如跳过了 mysql_upgrade 的等价步骤),会导致 performance_schema 表缺失、监控采集失败,而这个错误在日志里只表现为 “Table ‘performance_schema.xxx’ doesn’t exist”,不是 ERROR 级别,很容易被运维忽略。











