必须分三步走:先扫结构、再验逻辑、最后比行为。mysqlcheck --check-upgrade和util.checkForServerUpgrade()是升级前必须跑通的“安检门”,前者报MyISAM表等物理层问题,后者查SQL模式、保留字等逻辑层风险;mysqldump导出再导入可暴露sql_mode、字符集等隐性兼容问题;pt-upgrade回放真实SQL则验证GROUP BY、窗口函数等行为差异。

必须分三步走:先扫结构、再验逻辑、最后比行为。跳过任意一步,上线后大概率出问题。
用mysqlcheck和util.checkForServerUpgrade扫出硬性不兼容项
这两个工具不是可选,是升级前必须跑通的“安检门”。mysqlcheck --check-upgrade会立刻报出MyISAM表、分区语法错误、废弃引擎等物理层问题;util.checkForServerUpgrade()则深入到SQL模式、密码策略、保留字冲突等逻辑层。
- 执行
mysqlcheck -u root -p --all-databases --check-upgrade时,重点看是否提示MyISAM或ERROR 1176(键不存在但被引用) - 在MySQL Shell里运行
util.checkForServerUpgrade('root@localhost:3306', {targetVersion:'8.4'}),注意WARNING级输出——比如column name 'rank' conflicts with reserved keyword,这种不会中断升级,但后续查询会报错 - 别信返回
OK就万事大吉:util.checkForServerUpgrade默认只检查当前连接用户权限范围内的库,得用root账号全库扫描
用mysqldump分两阶段验证逻辑导入兼容性
导出再导入不是为了备份,而是为了触发新版本的解析器,暴露sql_mode、字符集、时间默认值这类隐性问题。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 第一阶段只导结构:
mysqldump --all-databases --no-data --routines --events --triggers > defs.sql,在8.4实例上执行mysql ,紧盯<code>ERROR 1231(STRICT_TRANS_TABLES拒绝空字符串)、ERROR 3719(utf8mb3被拒) - 第二阶段导数据:
mysqldump --all-databases --no-create-info --single-transaction > data.sql,导入时加--force继续,但必须记录所有ERROR 1292(类型截断转错误)——这类语句在5.7只警告,8.4直接失败 - 特别注意
--skip-triggers要单独测一次:有些触发器里用了OLD.table_name(8.0.19+已限制),不跳过会卡在ERROR 1356
用pt-upgrade对比真实查询行为差异
DDL能过不代表业务能跑。GROUP BY隐式排序取消、窗口函数优化路径变化、JSON返回类型调整,这些都得靠实际SQL回放来发现。
- 从生产环境抓取通用日志或慢日志,用
pt-upgrade --query-log=slow.log --new-host=84-instance --old-host=57-instance回放 - 结果表里重点盯
diff列:值为1表示结果集行数/内容不一致,不是性能问题,是行为变更 -
ERROR 1055(ONLY_FULL_GROUP_BY)最典型:5.7能跑的SELECT a, COUNT(*) FROM t GROUP BY b,8.4直接报错,必须改SQL或临时调sql_mode - 别只看主库:如果用了读写分离,得分别对主库和从库做
pt-upgrade,因为8.4的复制优化可能让从库执行计划不同
真正容易被忽略的,是那些没报错但结果不对的场景——比如ORDER BY字段名和SELECT别名同名时,8.4按标准SQL解析,5.7按MySQL旧规则处理,差一行数据都可能引发业务逻辑错乱。测试时得拿真实订单号、用户ID去比对,不能只看count(*)。

















