数据库版本升级

版本升级能带来性能、安全与新特性,但也是高风险操作。核心原则只有一条:先在演练环境完整走通,再在生产按可回滚的顺序执行。

通用流程

1. 评估    读官方 release notes,列出破坏性变更与废弃特性
2. 兼容    用官方检查工具扫描(如 MySQL Shell util.checkForServerUpgrade)
3. 演练    在等价测试环境完整升级 + 回归测试
4. 备份    全量备份 + 确认可恢复
5. 灰度    先升从库/备节点,验证复制与读流量
6. 切换    升级主节点,或滚动升级
7. 验证    功能、性能、复制、监控回归
8. 回滚    保留旧版本快照/实例,明确回退步骤
Warning

降级通常不受支持:数据文件升级到新版本后往往无法回退到旧版本。因此回滚方案的本质是「保留旧实例或旧快照 + 切回」,而不是「原地降级」。务必在升级前把这一点确认清楚。

MySQL 5.7 → 8.0

主要破坏性变更

变化影响与对策
默认字符集 utf8mb4表结构/连接字符集需核对
默认认证插件 caching_sha2_password旧客户端需升级或改用 mysql_native_password
sql_mode 更严格,ONLY_FULL_GROUP_BY 默认开启不合规的 GROUP BY 语句会报错,需改写
移除查询缓存query_cache_* 参数失效,直接删除
保留字新增(如 rankgroups作为列名/表名会报错,需加反引号或改名
utf8 别名改指 utf8mb3显式使用 utf8mb4

检查与升级

# MySQL Shell 提供的升级检查工具
mysqlsh -- util check-for-server-upgrade root@localhost:3306 \
  --target-version=8.0 --output-format=JSON
# 停止旧实例,用 8.0 的 mysqld 启动(数据目录自动升级)
systemctl stop mysqld@5.7
systemctl start mysqld@8.0
# 8.0 起不再需要显式运行 mysql_upgrade

大版本跨度过大或异构环境,更稳妥的是逻辑导出 + 导入

mysqldump --single-transaction --routines --triggers --all-databases > all.sql
mysql --default-character-set=utf8mb4 < all.sql
Tip

升级前重点回归 ONLY_FULL_GROUP_BY 相关的 SQL——这是 5.7→8.0 最常见的「升级即报错」来源。可先在 5.7 上开启该模式跑一段时间,提前暴露问题。

PostgreSQL 大版本升级

PG 的小版本升级兼容数据目录,只需替换二进制并重启;大版本(如 15→16)不保证二进制兼容,必须走 pg_upgrade 或逻辑方式。

方案停机说明
pg_upgrade(copy)复制数据文件,安全,需双倍空间
pg_upgrade --link硬链接,快,但回滚困难
逻辑复制最短新旧并行,跨版本对外同步,可灰度
pg_dump/pg_restore简单,适合小库
# 1. 初始化新版本数据目录
/usr/lib/postgresql/16/bin/initdb -D /data/pg16

# 2. 停机后执行升级检查与迁移
/usr/lib/postgresql/16/bin/pg_upgrade \
  --old-datadir=/data/pg15 --new-datadir=/data/pg16 \
  --old-bindir=/usr/lib/postgresql/15/bin \
  --new-bindir=/usr/lib/postgresql/16/bin \
  --check       # 先 --check,通过后去掉参数正式执行

升级后必须:

-- 更新统计信息与执行计划
VACUUM (ANALYZE, VERBOSE);

-- 重新生成优化器统计
ANALYZE;
Warning

大版本升级后,扩展(extension)需安装对应新版本,排序规则(collation)变更可能影响索引比较结果。跨大版本前务必核对扩展清单与 lc_collate/lc_ctype。逻辑复制方式还能顺带完成大版本迁移,且停机极小。

MongoDB 版本升级

  • 不能跳大版本:必须逐个(4.4 → 5.0 → 6.0 → 7.0)升级。
  • 升级顺序:先升 mongos → config server → shard(分片集群)。
  • 升级二进制后,再提升 FCV(featureCompatibilityVersion)
// 副本集升级完成后
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
db.adminCommand({ setFeatureCompatibilityVersion: "7.0" })
Tip

先把所有节点升级到新版本二进制、验证稳定后,设置 FCV 到新版本。FCV 是「真正启用新特性」的开关,也是回滚的缓冲:只要 FCV 未提升,仍可退回旧二进制。

Redis 升级

  • 复制架构下滚动升级:先升从节点 → 主从切换(FAILOVER/REPLICAOF)→ 再升原主节点。
  • RDB/AOF 格式向后兼容,但新版本生成的持久化文件可能无法被旧版本读取
  • Redis 7 引入了大量变更(如函数、FUNCTION、ACL 增强),升级前确认客户端与模块兼容。
redis-cli -h old-master FAILOVER TO new-master FORCE   # 主从切换
redis-cli -h old-master INFO server                    # 确认版本

回滚策略

场景回滚手段
原地升级失败恢复升级前快照/备份到旧版本实例
从库升级异常从库重建即可,不影响主库
MySQL 升级后应用报错保留旧实例可切回(因降级不受支持)
MongoDB FCV 未提升回退二进制即可
逻辑迁移保留源库,直接切回源库
Warning

没有回滚预案就不要开始升级。至少保留一份升级前的全量备份 + 一个可启动的旧版本实例(或快照),并明确「切回需要多久」。升级窗口应选在业务低峰。

升级前检查清单

  • 阅读官方 release notes,列出破坏性变更
  • 用官方工具(util.checkForServerUpgrade / pg_upgrade --check)扫描通过
  • 测试环境完整演练 + 回归测试通过
  • 全量备份完成且验证可恢复
  • 明确回滚方案与 RTO
  • 升级窗口在业务低峰,通知相关方
  • 升级后回归:功能、性能、复制、监控

小结

  • 通用流程:评估 → 兼容扫描 → 演练 → 备份 → 灰度 → 切换 → 验证 → 回滚。
  • MySQL 5.7→8.0 重点防 ONLY_FULL_GROUP_BY、认证插件与字符集变化。
  • PG 大版本用 pg_upgrade 或逻辑复制;升级后 VACUUM ANALYZE
  • MongoDB 逐版本升级,先升二进制再提 FCV;Redis 滚动升级 + 主从切换。
  • 降级通常不可行,回滚的本质是「保留旧实例 + 切回」。