升级MySQL前必须做三件事:完整备份并用mysqlcheck校验表结构、用sha256sum校验备份文件、确认无长事务和DDL;跨版本升级需注意sql_mode、认证插件、GROUP BY语义等兼容性变化。

升级前必须做的三件事
MySQL 升级不是“执行一条命令就完事”的操作,数据丢失往往发生在升级前的疏忽。最核心的预防动作是:完整备份 + 校验 + 停写确认。
-
mysqldump或Percona XtraBackup必须执行一次全量备份,且备份后要运行mysqlcheck --check验证表结构一致性 - 备份文件本身要通过
sha256sum校验,避免磁盘静默错误导致备份无效 - 升级前确认无长事务、无正在执行的 DDL(查
SHOW PROCESSLIST和SELECT * FROM information_schema.INNODB_TRX),否则ALTER TABLE可能被中断并卡住元数据锁
版本跨度过大时的兼容性陷阱
5.7 → 8.0 是高频升级路径,但默认行为变更极多,直接覆盖启动极易导致服务无法启动或查询结果异常。
-
sql_mode默认值变化:8.0 启用STRICT_TRANS_TABLES和NO_ENGINE_SUBSTITUTION,旧应用插入超长字符串会报错而非截断 -
mysql.user表结构重设计,plugin字段从mysql_native_password改为caching_sha2_password,老客户端连不上需显式指定--default-auth=mysql_native_password -
GROUP BY语义变严格:8.0 不再允许SELECT a, b FROM t GROUP BY a中的非聚合列b,需改写为ANY_VALUE(b)或补全GROUP BY a, b
in-place 升级失败后的回滚实操
使用 mysqld --upgrade=FORCE 强制升级后若启动失败,不要反复重试——InnoDB 的 ibdata1 可能已被部分修改,继续操作会扩大损坏面。
- 立即停止 mysqld 进程,检查错误日志末尾是否出现
InnoDB: Page directory corruption或Failed to initialize DD - 若备份可用,停服务后直接替换整个
datadir目录(含ib_logfile*、ibdata1),再用旧版本二进制启动并导出数据 - 若只有逻辑备份,切勿用新版本
mysqldump导入到旧实例——8.0 的DUMPFILE语法或JSON字段定义可能不兼容,应降级到对应版本的客户端执行mysql导入
升级后必须验证的四个关键点
升级完成不等于安全,很多问题在高并发或特定 SQL 下才暴露。
- 检查
SELECT VERSION(), @@GLOBAL.sql_mode是否符合预期,特别注意ONLY_FULL_GROUP_BY是否意外开启 - 运行
mysql_upgrade(仅 5.7 及以前)或mysqld --upgrade=FORCE(8.0+)后,必须重启服务,否则数据字典不会真正更新 - 对所有使用
ENUM、SET、BIT类型的表执行CHECK TABLE ... EXTENDED,这些类型在 8.0 的排序和比较逻辑有调整 - 触发一次真实业务读写流量(哪怕只跑 5 分钟),重点观察慢查询日志中是否新增大量
Using temporary; Using filesort,这可能是隐式类型转换或索引失效的信号
真正危险的不是升级动作本身,而是把“备份做了”当成“数据保住了”。校验备份可恢复性、确认客户端兼容性、留好旧版二进制包——这些动作没做全,升级就只是把故障时间从“现在”推迟到了“半夜报警时”。










