30.2 三类大版本升级路径
大版本升级没有统一最优解。路径选择本质上是在四种成本之间交换:
先写约束,再选工具;不能因为团队最熟 pg_upgrade,就把所有数据库都压进一个停机
窗口。
30.2.1 pg_upgrade 与停机窗口
它升级 cluster,不是逐条重写业务数据
pg_upgrade 用新版本创建系统目录,再迁移旧 cluster 的 catalog 与用户 relation 文件,
因此通常比逻辑 dump/restore 快得多。它要求:
- old/new server binaries 与 data/config directories 都可用;
- compile-time 与 control-data 条件兼容;
- 新 major 对应的扩展 shared libraries 已安装;
- 两个 cluster 在正式 upgrade 时都停止;
- 操作系统用户/数据库 install user、认证和 socket 可连接;
- tablespace、standby、slot、统计与生成的 rebuild scripts 都有计划。
永远运行新版本的 pg_upgrade:
--check 应在彩排和正式窗口前重复执行。若计划使用特定传输模式,检查时也要带相同
模式,才能覆盖文件系统约束。
文件传输模式决定速度和回退形态
| 模式 | 空间/速度 | old cluster 可回退边界 |
|---|---|---|
default --copy |
需要完整副本,较慢 | old relation files 独立,新端启动后仍可启动旧端 |
--copy-file-range |
可能利用高效内核复制 | 取决于实际文件系统行为,仍需实测 |
--clone |
CoW 文件系统上快且省空间 | 新旧逻辑独立,但要求文件系统支持 |
--link |
硬链接,最快且省空间 | 新端一旦启动写共享文件,旧端不再安全 |
--swap |
可能更快,直接交换目录内容 | 传输进入破坏阶段后旧端不再安全 |
不能把 --link 的分钟级结果与 --copy 的回退承诺同时写进 runbook。选择哪个模式,
就必须演练哪个模式、同一种文件系统、同样 tablespace 布局与数据规模。
本章为了验证“目标零写入时旧端可启动”,明确使用 --copy,禁止 link、clone、swap
和 --no-sync。升级完成后新 PG18 已启动并校验,随后停止新端、启动旧 PG17,
10,000 行 manifest 仍相等。这个结论只属于 copy 模式和本次 fixture。
停机窗口不只是一条命令的秒数
业务不可写窗口通常包含:
pg_upgrade 输出的 Upgrade Complete 只是中点。它会提示需运行的 rebuild/reindex
脚本;被这些脚本引用的表在完成前可能返回错误结果或性能极差。PostgreSQL 18 会迁移
大部分优化器统计,但 extended、扩展自定义和累计统计并不完整,仍建议:
彩排要分别计时每一阶段,以生产数据克隆的 P95/P99 结果安排窗口,不能拿一个 10,000
行实验的 pg_upgrade 时间乘比例。
30.2.2 逻辑复制与渐进切换
逻辑复制把新 major 建成独立 cluster:
它的优点:
- 业务不可写时间主要集中在最终冻结与切流;
- 新旧环境可同时运行,便于真实应用影子验证;
- 可以跨平台、改变物理布局、重配参数和扩展;
- 目标可逐步扩容与预热。
代价已经在第 29 章验证:
- DDL、sequence、large object 与许多对象不自动复制;
- publication/subscription、replica identity、slot WAL 必须治理;
- 目标写入会制造冲突或 silent drift;
- 全量、增量、业务不变量和切流路由都需独立证据;
- 回退在目标承接写入后需要 reverse sync 或 reconciliation。
跨 major 还要检查 row/column filter、generated columns、binary transfer 与协议选项在 两个版本交集中的语义。一般先升级 subscriber/target 能扩大兼容余量,但具体拓扑 需按官方 logical replication upgrade 章节执行。
PostgreSQL 17 起,pg_upgrade 可以在满足前提时迁移 logical slot/subscription
依赖;这不意味着任意逻辑复制拓扑能自动升级。publisher upgrade 前需要停用对应
subscription,循环、多节点和 two-phase 拓扑有非事务步骤,必须有备份和逐节点状态机。
Pigsty 推荐生产 major upgrade 优先考虑新建集群 + 逻辑迁移,因为它把应用验证和资源 准备移到切换前。这里的“推荐”仍需服从数据对象是否可逻辑复制、写入率、slot 容量、 DDL 频率和团队能否可靠完成对账。
30.2.3 dump/restore 与重建机会
dump/restore 是最“逻辑化”的升级:在新 cluster 按新版本规则重新创建对象和写入行。 它成本高,却也是一次摆脱历史物理包袱的机会:
- 重排 tablespace、partition 与对象 owner;
- 只迁移仍需保留的数据;
- 统一 encoding/locale 的新建策略;
- 重建全部 index,消除旧物理布局;
- 审阅 schema、extension、privilege 和废弃对象;
- 用 directory archive 并行 dump/restore。
常见路径:
选择性恢复不是“完整 cluster 迁移”的同义词。需要另外处理:
使用 target major 的 pg_dump,并读取 stderr 全部 warning。directory 格式是唯一支持
parallel dump 的 archive;custom/directory 都支持选择与重排 restore。并行增加
jobs + 1 个连接和源端负载,还可能因 DDL lock 排队而失败,必须在生产形态彩排。
dump/restore 的回退与逻辑迁移相似:旧端可继续保留,但目标开始承接独占写入后,改回 连接串仍会丢新事实。它不是因为“重建了一份”就天然可逆。
30.2.4 没有一种路径天然“滚动无感”
用约束选型
| 约束 | pg_upgrade |
logical replication | dump/restore |
|---|---|---|---|
| 最小写停机 | 较弱 | 强 | 较弱 |
| 额外硬件 | 可同机 | 通常需要完整新集群 | 通常需要完整新集群 |
| 升级速度 | 通常最快 | 取决于全量 + 追平 | 通常最慢 |
| 真实影子验证 | 有限 | 最强 | 恢复完成后可做 |
| 改物理布局 | 有限 | 强 | 最强 |
| DDL/sequence 编排 | 中 | 最复杂 | restore 负责大部分 |
| 旧端物理回退 | 取决于 copy/link/swap | 切流前强 | 切流前强 |
| 数据对账 | 必需 | 最重 | 必需 |
一个常见组合不是三选一,而是:
甚至同一项目会先用 dump/restore 生成测试克隆,再用 pg_upgrade 彩排正式路径。
“无感”要拆成多个 SLO
所谓无感至少包含:
逻辑切换只有几秒写冻结,不代表旧池里的长事务、prepared statement、sequence、
缓存、ETL 与外部副作用无感。minor rolling 也会发生连接断开和 failover。pg_upgrade
即使文件迁移很快,post-upgrade reindex/ANALYZE 仍可能控制上线时间。
所以 runbook 不写“无感升级”,而写:
可测量的预算才是发布决策;“滚动”“在线”“秒级”只是实现特征。
上一节:先识别变化类型 · 返回本章目录 · 下一节:扩展与依赖升级 · 查看全书目录 · 查看索引中心