mysql升级前必须验证:表结构兼容性(如utf8mb3→utf8mb4)、sql mode变更、认证插件切换、gtid复制一致性、系统表空间加密状态及performance_schema指标启用。

MySQL升级前必须验证的兼容性检查项
MySQL大版本升级(如 5.7 → 8.0)不是简单替换二进制文件,很多语法、权限模型和默认行为已变更。跳过兼容性检查直接升级,大概率导致应用启动失败或查询结果异常。
- 用
mysql_upgrade已废弃(8.0.16+ 移除),改用mysqld --upgrade=FORCE或mysql_upgrade的替代流程需明确 - 必须运行
mysqlcheck --all-databases --check-upgrade检查表结构是否兼容新版本(尤其注意utf8mb3到utf8mb4默认变更) - 检查 SQL mode:8.0 默认启用
STRICT_TRANS_TABLES和ONLY_FULL_GROUP_BY,旧应用可能报错 - 确认所有用户使用的是
caching_sha2_password插件(8.0.4+ 默认),否则客户端连接会失败,需提前执行ALTER USER ... IDENTIFIED WITH mysql_native_password
用 Percona Toolkit 自动化预检与数据迁移
Percona Toolkit 中的 pt-upgrade 和 pt-online-schema-change 不是升级工具本身,但能极大降低升级风险。它们帮你模拟新版本行为、识别潜在不兼容 SQL,并支持零停机调整表结构以适配新版本要求。
-
pt-upgrade可对比同一份慢日志在 5.7 和 8.0 实例上的执行结果差异,暴露隐式类型转换、排序变化等“静默错误” - 升级前若存在大表未使用
utf8mb4,用pt-online-schema-change --charset=utf8mb4安全转换,避免锁表 - 注意:8.0.29+ 对
pt-online-schema-change的兼容性有修复,低于该版本建议升级 PT 到 3.5.0+
pt-upgrade --old-host=old-db --new-host=new-db --user=admin --password=xxx /var/log/mysql/slow.log
用 Ansible 编排多节点 MySQL 升级流程
手动逐台升级高可用集群(MHA / Orchestrator / InnoDB Cluster)极易出错。Ansible 能强制执行顺序、校验状态、自动回滚,是生产环境升级的事实标准编排方式。
- 关键控制点必须写入 playbook:
wait_for等待从库 SQL_THREAD 停止、assert校验SELECT VERSION()输出、shell模块中用mysql -e "SHOW SLAVE STATUS\G" | grep -q "Seconds_Behind_Master: 0"确认同步完成 - 主库升级前,务必先
STOP SLAVE并确认所有从库已追平(Exec_Master_Log_Pos一致),否则 GTID 模式下可能产生不可逆复制断裂 - 升级脚本中禁止硬编码密码;用
ansible-vault加密敏感变量,或通过mysql_config_editor配置登录路径后让mysql命令自动读取
升级后必须立即执行的三项验证
二进制替换成、服务起来、SELECT VERSION() 返回正确值 ≠ 升级成功。很多问题会在业务高峰或特定查询路径下才暴露。
- 检查
performance_schema.replication_applier_status_by_coordinator是否为空(GTID 模式下 coordinator 线程异常会导致复制卡死) - 运行
SELECT * FROM information_schema.INNODB_METRICS WHERE NAME LIKE 'buffer%',确认缓冲池指标可正常采集(8.0 默认关闭部分 metrics,需显式SET GLOBAL innodb_monitor_enable = 'buffer%) - 用应用真实 SQL 测试事务隔离级别行为:8.0 中
READ-COMMITTED下的 semi-consistent read 行为变化,可能影响乐观锁重试逻辑
升级最易被忽略的点:系统表空间加密(innodb_encrypt_tables=ON)在 5.7 和 8.0 间不兼容,若原实例启用了加密,必须在升级前用 ALTER TABLE ... ENCRYPTION='N' 解密,否则 8.0 启动失败且无法降级。










