升级前必须做的三件事
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,这可能是隐式类型转换或索引失效的信号
真正危险的不是升级动作本身,而是把“备份做了”当成“数据保住了”。校验备份可恢复性、确认客户端兼容性、留好旧版二进制包——这些动作没做全,升级就只是把故障时间从“现在”推迟到了“半夜报警时”。
