最轻量有效的MySQL主版本升级兼容性测试方式是mysqldump导出再导入:用旧版mysqldump(含--routines --triggers --events)导出,新版mysql客户端导入,重点检查sql_mode、时间默认值、字符集等错误;必须验证触发器、系统表、查询一致性、主从切换及周边链路。

用 mysqldump + 模拟升级验证兼容性
MySQL 主版本升级(如 5.7 → 8.0)前,最轻量但有效的测试方式是导出再导入:在测试机上用旧版本 mysqldump 导出全库(含 --routines --triggers --events),再用新版本 mysql 客户端导入,观察是否报错。
重点检查以下几类错误:
-
ERROR 1231 (42000):常见于sql_mode变更(如 8.0 默认启用STRICT_TRANS_TABLES) -
ERROR 1067 (42000):时间字段默认值不合法(如0000-00-00被拒绝) -
ERROR 3719 (HY000):字符集相关(utf8mb3已弃用,需提前改为utf8mb4)
注意:不要跳过 --skip-triggers 测试——有些触发器里用了已移除的语法(如 OLD.table_name 在 8.0.19+ 中受限)。
用 mysql_upgrade 检查系统表兼容性
升级二进制包或 RPM 后,必须运行 mysql_upgrade(8.0.16+ 已移除该命令,改由 mysqld 自动执行,但需确认 mysql.system_versioning 等新表是否存在)。
实操建议:
- 先停掉新版本
mysqld,手动备份mysql库(cp -r /var/lib/mysql/mysql /backup/mysql_pre_upgrade) - 启动新版本时加
--skip-grant-tables和--skip-networking,仅本地执行校验 - 运行
SELECT * FROM mysql.innodb_table_stats,若报Table doesn't exist,说明统计表未初始化,需mysql_upgrade或手动执行mysql_system_tables.sql
用 pt-upgrade 对比查询结果一致性
仅验证 DDL 不够,业务 SQL 行为可能变化(如 8.0 的窗口函数优化、GROUP BY 严格模式、JSON 函数返回类型差异)。Percona Toolkit 的 pt-upgrade 可抓取生产慢日志或通用日志,在新旧实例上回放并比对结果。
关键配置项:
-
--run-time=300控制回放时长,避免拖太久 -
--query-review-table指定结果对比表,需提前在两个实例中建好 - 遇到
ERROR 1292 (22007)(截断警告转错误)要特别标记——这类语句在 5.7 只告警,8.0 直接失败
注意:pt-upgrade 不支持 MySQL 8.0 的角色(ROLE)权限模型,若线上用了角色,需先降级为用户权限再测试。
模拟主从切换验证高可用链路
如果用 MHA、Orchestrator 或自研切换脚本,升级后必须在测试环境走完整 failover 流程:先升从库,再升主库,最后执行一次人工切换,确认监控、VIP、应用连接池能否自动恢复。
容易忽略的点:
- GTID mode 开启后,
CHANGE MASTER TO语法必须用MASTER_AUTO_POSITION = 1,旧脚本若硬编码MASTER_LOG_FILE会失败 - 8.0 默认
binlog_transaction_compression = ON,老版本从库无法解析压缩事务,主从复制中断 - 应用连接串里的
allowPublicKeyRetrieval=true在 8.0.23+ 中被废弃,需改用serverRSAPublicKeyFile
真实升级中最常卡住的不是 SQL 兼容性,而是这些“周边链路”的隐式依赖——比如备份工具调用的 mysqlbinlog 版本不匹配,或监控脚本里解析 SHOW SLAVE STATUS 的字段名变了(Seconds_Behind_Master 在 8.0.22+ 中对延迟从库可能为 NULL)。










