pg_upgrade 大版本升级:11 到 14 的停机窗口内完成
PG 11 到 14 的升级项目,业务给的停机窗口只有 4 小时。物理复制做不了跨版本(PG16 的逻辑复制也只有部分 DDL 支持),最终用 pg_upgrade 硬链模式完成,实际停机 38 分钟。把方案和过程记录下来。
pg_upgrade 的原理是"就地转换":新旧两个集群装好(旧 11 新 14 各一个数据目录),它对比两边的系统目录,把用户数据文件的文件级别硬链接到新集群(--link 模式),只重写必须变的部分。数据文件不拷贝,这是它快的根本原因。升级前必须跑一次检查模式,把阻断项清零:扩展版本兼容(老版本 postgis 之类要先在旧库升级扩展)、预处理事项、collation 变化(11 到 14 的 glibc 或 ICU 差异可能导致索引损坏,官方要求升级后重建所有索引,amcheck 验证)。
窗口内的动作序列:
# 1. 停应用写入,旧库停机前抓最终状态
pg_ctl -D /pg11 stop
# 2. 检查模式先跑过(窗口前已验证无 Fatal 项)
# 窗口内正式升级:硬链接模式,11TB 走了 12 分钟
pg_upgrade --old-datadir /pg11 --new-datadir /pg14 --old-bindir /usr/lib/postgresql/11/bin --new-bindir /usr/lib/postgresql/14/bin --link --jobs=8
# 3. 升级自带脚本更新优化器统计信息(analyze_new_cluster.sh)
# 4. 按官方建议重建索引 + amcheck 校验
reindexdb --all
38 分钟的构成:停写检查 5 分钟、pg_upgrade 12 分钟、analyze 8 分钟、索引重建排到窗口后异步(只重建关键表)、应用连接切换与验证 13 分钟。analyze 不能省,新版本优化器的统计信息格式不同,跳过会导致执行计划集体漂移。
升级窗口后的性能回归也有一套:把 TOP 100 SQL 的执行计划哈希在升级前后各采集一次,diff 出计划变化的语句逐一评估。我们那次抓到 7 条计划漂移,其中 2 条靠更新统计信息恢复、5 条确认无害。没有这步验证,升级成功只是没有立刻出事的同义词。
预案里准备但没用上的备胎:pg_dump 逻辑导出(要 6 小时,超窗口放弃)和逻辑订阅升级(做备用从库,随时可回切)。升级后观察一周,确实抓到两个执行计划劣化的 SQL,14 的优化器对 nested loop 的成本模型变了,analyze 之后重新 autovacuum 即恢复。版本升级这类项目,功夫全在窗口之外:检查项清零、演练两轮、回退路径演练、每分钟都有 checklist,窗口内只是照着剧本走。
- 点赞
- 收藏
- 关注作者
评论(0)