AustinDatabases

PostgreSQL 版本升级方法总结,具体pg_upgrade怎么操作

❝

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群加群请联系 liuaustin3 ,(共3400人左右 1 + 2 + 3 + 4 +5 + 6 + 7 + 8 )(1 2 3 4 5 6 7 8群已经爆满  9群 为纯聊天群,默认不加入不得发广告,自己公众号文章链接等,发一次直接踢,默认加入8群,开10群PolarDB专业学习群115+)

POSTGRESQL 的版本在快速的更新,之前存在的BUG在不断被填补,一大部分原有的数据库企业用户还停留在PG13 14 15 这几个版本,企业用户在选定版本后,不会轻易的更新版本,而这几年PG17 PG18的一些核心的功能的更新明显提升了数据库的性能,

随着硬件的昂贵,使用更先进的数据库程序,降低硬件的成本是当前很多数据库用户的选择。所以升级数据库是一个后期的必要的工作,下面我们以PG14升级到PG16作为一个基础来说说常见的数据库升级的方案有哪些。

1 升级我们能获得什么

Image

随着数据库运行时间越来越长,数据量不断增加,查询越来越复杂,原来的性能瓶颈往往并不只是 SQL 写得不好。PostgreSQL 14 到 PostgreSQL 16 之间,在并行查询、VACUUM、查询执行器以及连接建立等方面都进行了持续优化。

对于一些数据量比较大的系统来说,并行查询能力的提升,可以让数据库更有效地利用多核 CPU;VACUUM 性能的改进,则意味着在高频更新、删除的业务环境中,可以更好地处理表膨胀和垃圾数据问题;而查询执行器和连接建立过程的优化,也能够进一步降低数据库在高并发环境下的资源消耗。

另外,随着 JSON 数据越来越多地进入企业系统,PostgreSQL 对 JSON 处理能力也在不断增强。过去很多企业只是把 PostgreSQL 当成一个传统关系型数据库使用,但现在越来越多的业务开始同时处理关系型数据、半结构化数据,数据库的使用方式已经发生了变化。

除了性能之外,PG16 还有一个非常重要的价值,就是功能上的持续演进。

比如逻辑复制能力的增强。

对于很多企业来说,数据库升级最怕的并不是“升级失败”,而是升级过程中业务不能停。逻辑复制的不断完善,使 PostgreSQL 在在线迁移、异地同步、数据分发以及版本升级等场景中有了更多的选择。

最后,还有一个问题,其实比性能和新功能更加现实。

那就是:PG14 还能维护多久?

很多企业在做数据库升级时,最大的误区就是只看当前系统能不能运行。

系统能运行,并不代表它适合长期继续运行。

一个版本进入生命周期后期之后,企业需要考虑的不只是功能问题,还包括安全补丁、社区支持、第三方工具兼容性,以及未来操作系统和基础设施升级之后的兼容问题。

所以,从 PG14 升级到 PG16,本质上并不是简单地把版本号从 14 改成 16。

它实际上是在做几件事情:

一是通过新的执行器、并行查询和 VACUUM 优化,提升数据库在未来业务增长过程中的性能能力。

二是通过逻辑复制、分区表、SQL/JSON 等能力,为未来的数据架构留下更多空间。

三是通过 pg_stat_io 等监控能力,提高数据库的可观测性,降低 DBA 排查问题的难度。

四是通过进入新的长期支持周期,减少企业未来在安全和维护方面的不确定性。

Image
Image
Image

这里有四个方案

  1. pg_upgrade 原地升级方案

优点:

速度极快:若使用硬链接模式(--link),升级时间仅取决于元数据处理时间,几 TB 数据通常可以在几分钟内完成。

资源占用低:硬链接模式下不需要额外的双倍存储空间。

缺点:

难以快速回滚:一旦升级失败或切流后发现业务异常,无法原位回滚,只能通过升级前的冷备或 PITR 物理备份重新恢复数据。

需短暂停机:升级过程中源库必须处于完全停机状态,无法实现零停机。

风险与危险性:

破坏性风险:在 --link 模式下,旧库的数据文件会被直接修改。若升级中途意外中断(如断电、磁盘满),旧库数据可能损坏且无法重新启动。

兼容性隐患:跨版本插件(Extensions)、自定义函数或废弃参数不兼容会导致升级流程报错中断。

  1. 逻辑复制方案(Logical Replication / pg_logical)

优点:

极短停机:新旧库可并行运行,通过后台实时追赶增量,业务切换只需秒级/分钟级的切流窗口。

具备完备回滚方案:可搭建“反向逻辑复制(Reverse Replication)”,切流后若新库出现故障,可迅速切回旧库且不丢失切流后的新数据。

跨平台/版本能力强:支持跨大版本、跨 OS 系统、甚至跨不同硬件架构进行迁移。

缺点:

运维复杂度高:需要配置发布(Publication)和订阅(Subscription),且需要额外监控复制延迟。

资源消耗高:源库解析 WAL 日志(Logical Decoding)会占用额外的 CPU、内存及磁盘 I/O。

风险与危险性:

数据遗漏风险:逻辑复制默认不支持 DDL 语句自动复制,且对无主键表(PK)、序列(Sequence)自增状态、大对象(Large Objects)等支持较差,容易引发数据不一致或主键冲突。

复制积压风险:若源库写吞吐极高,逻辑复制可能长时间追不上延迟,导致升级窗口无限拉长。

  1. pg_dump / pg_dumpall 逻辑导出导入方案

优点:

完全整理物理碎片:导出导入相当于重新建表重写数据,能够彻底解决表膨胀(Bloat)和索引碎片问题。

操作简单:命令工具成熟,兼容性极好,出错时旧库完好无损,随时可以放弃重新来过。

缺点:

耗时极长:导出和导入过程完全受限于单线程/多线程 CPU 和磁盘 I/O 速度,大库(百 GB 以上)停机时间不可接受。

资源消耗巨大:导入阶段会触发密集的索引重建和写 WAL,对目标库硬件性能要求极高。

风险与危险性:

停机超时风险:随着数据量增加,导入与建索引时间极易超出预定的维护窗口,导致升级超时。

数据类型与语法风险:跨大版本时,若遇到已弃用的数据类型或内置函数,导入过程中可能频繁报错终止。

  1. 物理复制方案(Physical Streaming Replication)

优点:

数据高度一致:基于物理 Block 层的块级别复制,RPO 近乎为 0,且搭建与运维非常简单成熟。

主机压力小:对源库性能影响极小。

缺点:

无法直接跨大版本:PostgreSQL 不支持跨大版本的物理流复制(旧版本的 WAL 无法被新版本的引擎应用)。

通常需结合 pg_upgrade 使用:实际落地时,通常是搭建一个物理备库,将备库提升为主库后,在备库上执行 pg_upgrade(以保护原生产主库)。

风险与危险性:

认知误区风险:若误以为能直接将新版本节点作为旧版本节点的物理备库进行实时复制,会导致启动直接报错崩溃。

切换链路风险:若采用“备库做 pg_upgrade”的折中方案,切流前主备中断同步的瞬间依然存在数据缝隙,需要严格校验 WAL 接收点。

升级前的评估与准备

## 1. 当前 PG14 环境信息

# 查看版本详情
psql -c "SELECT version();"

# 查看数据目录
psql -c "SHOW data_directory;"

# 查看数据量
psql -c "SELECT pg_size_pretty(pg_database_size(current_database()));"

# 查看所有数据库大小
psql -c "SELECT datname, pg_size_pretty(pg_database_size(datname)) 
          FROM pg_database ORDER BY pg_database_size(datname) DESC;"


# 查看表数量和总大小
psql -c "SELECT count(*) as table_count, 
          pg_size_pretty(sum(pg_total_relation_size(oid))) as total_size
          FROM pg_class WHERE relkind = 'r';"


# 查看已安装的扩展
psql -c "SELECT * FROM pg_extension;"

# 查看自定义数据类型
psql -c "SELECT n.nspname, t.typname 
          FROM pg_type t JOIN pg_namespace n ON t.typnamespace = n.oid
          WHERE n.nspname NOT IN ('pg_catalog', 'information_schema');"


# 查看当前连接配置
psql -c "SELECT name, setting, source FROM pg_settings WHERE source != 'default';"

# 查看 pg_hba.conf 规则
cat $(psql -tAc "SHOW hba_file;")

# 查看分区表
psql -c "SELECT inhparent::regclass as parent, inhrelid::regclass as child
          FROM pg_inherits;"


# 查看逻辑复制槽
psql -c "SELECT * FROM pg_replication_slots;"

兼容性的检查

## 2. 检查不兼容变更

# 检查使用的已弃用特性
# PG15 弃用: 
#   - ENABLE_ROW_SECURITY 参数
#   - 某些系统目录变更
# PG16 弃用:
#   - GRANT ... WITH ADMIN OPTION 语法变更
#   - CONNECT 权限行为变化

# 检查扩展兼容性
psql -c "SELECT extname, extversion FROM pg_extension;"
# 确认每个扩展在 PG16 中有对应版本

# 检查数据类型兼容性
psql -c "SELECT typname FROM pg_type WHERE typtype = 'e';"
# 枚举类型在升级中需要特别注意

# 检查存储过程和函数
psql -c "SELECT proname, prolang::reglanguage 
          FROM pg_proc WHERE pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');"


# 检查触发器
psql -c "SELECT tgname, tgrelid::regclass FROM pg_trigger WHERE NOT tgisinternal;"

升级前检查清单(PG14 → PG16)

  1. PG14版本检查 使用 SELECT version(); 确认当前 PostgreSQL 版本是否为最新小版本(例如 14.12 及以上)。 通过标准:版本满足最新稳定小版本。 状态:未完成 / 已完成。

  2. 磁盘空间检查 执行 df -h 查看磁盘剩余空间。 通过标准:剩余空间至少为数据目录大小的 2 倍,以确保升级过程中的文件复制与日志写入。 状态:未完成 / 已完成。

  3. 完整备份确认 使用 pg_basebackup 或 pg_rman 完成全量备份,并验证备份可恢复。 通过标准:备份文件完整、恢复测试通过。 状态:未完成 / 已完成。

  4. 扩展兼容性检查 通过 SELECT * FROM pg_extension; 查看当前所有扩展。 通过标准:所有扩展均有 PG16 对应版本或兼容说明。 状态:未完成 / 已完成。

  5. 应用兼容性测试 在测试环境中完成应用功能验证,包括 SQL 行为、驱动版本、ORM 兼容性等。 通过标准:所有业务功能正常,无异常 SQL 行为。 状态:未完成 / 已完成。

  6. 维护窗口确认 与业务方确认升级时间窗口,确保停机或降级模式已获批准。 通过标准:维护窗口已正式预约。 状态:未完成 / 已完成。

  7. 回滚方案准备 编写回滚文档并在测试环境验证回滚步骤,包括恢复备份、切换配置等。 通过标准:回滚流程可执行且已验证。 状态:未完成 / 已完成。

  8. 监控与告警准备 为新版本实例配置监控项(连接数、延迟、WAL、扩展指标等),并设置告警规则。 通过标准:监控正常、告警策略已启用。 状态:未完成 / 已完成。

基于其他的方案的常规造作性这里就不在赘述,我们仅对pg_upgrade的方式来进行描述

pg_upgrade升级方式的工作原理与总结

pg_upgrade 是 PostgreSQL 官方提供的原地升级工具,它直接复用现有数据文件,通过转换系统目录来完成版本升级。这是最快速、最常用的升级方式。

Image
# 先运行检查模式 (--check),不实际升级
sudo -u postgres /usr/pgsql-16/bin/pg_upgrade \
    --old-datadir=/var/lib/pgsql/14/data \
    --new-datadir=/var/lib/pgsql/16/data \
    --old-bindir=/usr/pgsql-14/bin \
    --new-bindir=/usr/pgsql-16/bin \
    --check

# 正式执行升级
# 注意: 不加 --link 参数,保留旧数据目录用于回滚
sudo -u postgres /usr/pgsql-16/bin/pg_upgrade \
    --old-datadir=/var/lib/pgsql/14/data \
    --new-datadir=/var/lib/pgsql/16/data \
    --old-bindir=/usr/pgsql-14/bin \
    --new-bindir=/usr/pgsql-16/bin \
    --jobs=4 \
    --link

关于 --link 参数的选择
使用 --link: 升级更快、不占额外磁盘空间,但旧数据目录的文件被硬链接到新目录,无法独立启动旧版本回滚。

不使用 --link: 升级稍慢、需要额外磁盘空间复制数据,但旧数据目录完整保留,可随时回滚。

建议: 如果磁盘空间充足且需要回滚保障,不使用 --link。如果磁盘空间紧张且已通过备份保障回滚,可使用 --link。


# 复制 PG14 的配置文件到 PG16
sudo cp /var/lib/pgsql/14/data/postgresql.conf /var/lib/pgsql/16/data/
sudo cp /var/lib/pgsql/14/data/pg_hba.conf /var/lib/pgsql/16/data/
sudo cp /var/lib/pgsql/14/data/pg_ident.conf /var/lib/pgsql/16/data/

# 调整配置中的版本特定参数
sudo vi /var/lib/pgsql/16/data/postgresql.conf
# 检查并更新:
#   - shared_preload_libraries (确认扩展兼容)
#   - 任何 PG16 已弃用的参数

# 配置 systemd 服务
sudo systemctl enable postgresql-16

# 启动 PG16
sudo systemctl start postgresql-16


与OceanBase集中式摸爬滚打的4个月,我得到了什么 ?
醋评 数据库行业 “不行了”  ---来自五彩斑斓乌鸦的 3336个字
《没有人为不需要的性能付费 经济下行,正在倒逼数据库"做减法"》

PostgerSQL 14-17备份的变化 PG17更贴近商业数据库 与 实际命令

PostgreSQL 怎么用好高版本的PG调优--PG14-PG18

同学问 PG17 的备份比老的版本 好哪了? 你给总结总结 !!

算法领主与数据农奴:AI时代的不能说的问题-- 此文为AI临时工所做与公众号作者无关

《AI为什么迟迟进不了企业核心系统?我总结了八个原因》

《AI不是出事了,而是我们开始看到它的代价》
NOSQL 怎么翻盘,降本增效为企业节省资源,--DTCC 通过NOSQL给企业系统瘦身

怎么AI设定评估成本模型思考

MySQL 写不进去数据,程序报错,谁的问题?

从亚马逊 AGI 部门裁员看 AI 商业逻辑的必然转向  -- 资本不会给AGI 半点脸

比起简单的Skill技能,我更想建立Agent Skill的系统思维能力--- 感谢本书作者答疑解惑

  MongoDB 全文索引 与 展示查询数据的一部分,提高性能

体现价值-我们靠PostgreSQL迁移PolarDB,给公司省下了100万 “巨款”

《告别迁移焦虑:OceanBase MySQL 模式能否兼容 DBA 的“祖传”运维 SQL?》

干数据库不是买白菜:光盯着License几毛钱,看不见300台机器的电费?

一个秘密,不是你 SQL 写对了,是优化器帮“擦了屁股”  客户问迁移后为什么快了--迁移到PolarDB后的故事

AI 时代,我却用不上一个靠谱的数据库产品

AI 引入后,MySQL 列权限控制,插入,更新,读取,删除 --有了AI 真是越帮越忙

PostgreSQL 大表改字段卡死的问题解决了吗?  解决了方案在此

AI 引入DBA 工作,造成工作量增加,忙不过来,根本忙不过来!!!

三无项目导致MongoDB 持续1406% CPU 问题解决

Image