这是本节的多页打印视图。 .
文章
- 1: SOW:论母猪的产后护理
- 2: 上游没有的 Bug,为什么会出现在官方包里?
- 3: 瞬间克隆 PostgreSQL 数据库,无需黑魔法
- 4: 什么是 PostgreSQL 发行版?
- 5: 人人可用的 PG 扩展
- 6: 504 个扩展,PG 生态的天花板在哪?
- 7: PG 扩展百科全书:中英双语,开箱即用
- 8: 464个扩展开箱即用:新版 PG 扩展目录发布
- 9: 立足中国,面向全球的 PostgreSQL 发行版
- 10: 聊聊开源软件供应链信任问题
- 11: PG扩展云:解锁 PG 生态的全部潜力
- 12: 冷门但稀缺的技能:打包构建
- 13: 从PG“断供”看软件供应链中的信任问题
- 14: 卡脖子:PGDG切断镜像站同步通道
- 15: Postgres Extension Day,咱们不见不散
- 16: 小猪骑大象:PG内核与扩展包管理神器
- 17: PostgreSQL神功大成!最全扩展仓库来了!
这里收录 PIG 所要解决的问题:怎样发现 PostgreSQL 扩展,怎样把它们构建成原生 RPM/DEB 软件包,怎样发布可信的软件仓库,以及怎样通过实用的命令行工具把这些能力交给用户。
文章保留原始发表日期、当时的软件包数量、截图与上下文。当前行为请以 PIG 文档、 实时扩展目录与发布注记为准。
建议按以下线索阅读:
- PIG 与猪猪家族: 认识 PIG、瞬间克隆 PostgreSQL,以及 SOW 的仓库状态模型。
- 扩展交付: 最初的扩展仓库思考、PG 扩展云、扩展百科全书,以及人人可用的 PG 扩展。
- 打包与信任: 为什么 Linux 打包如此稀缺、PGDG 镜像事件、Pigsty 的回应,以及 Valkey 打包 Bug 的教训。
- 发行版这一层: 打造面向全球的 PostgreSQL 发行版,以及什么是 PostgreSQL 发行版。
1 - SOW:论母猪的产后护理
今天老冯来和大家聊一聊《母猪的产后护理》。俺做的新开源项目 SOW,翻译成中文就是“老母猪”。
做一个 PostgreSQL 发行版,最折磨人的往往不是把软件编译出来,而是收拾编译出来的东西。
Pigsty 要为多个 Linux 发行版、多个 CPU 架构、多个 PostgreSQL 大版本维护成百上千个组件。不同组合一路展开,最终落到仓库里的制品超过十万个:RPM、DEB、索引、签名、校验和、快照,还有一堆为了兼容包管理器而存在的元数据。
用户看到的只是 apt install 或 dnf install。维护者看到的却是另一幅画面:你只更新了一个包,却必须保证另外九万九千九百九十九个对象没被误删;你只改了一份索引,却必须保证全球用户不会在切换瞬间读到一半新、一半旧的仓库。当仓库小的时候,这些事都像脚本题。仓库大到十万个制品之后,它突然变成了一道数据库题、分布式系统题,还是一道供应链安全题。
所以我写了 SOW —— 一个用 Go 编写的自包含 APT / YUM 软件仓库管理器。

如果你只是想把一个目录里的 RPM / DEB 变成可用仓库,一条命令就够了:
如果你要长期维护仓库,SOW 还提供 Managed 模式:一份包体投影成多个发行视图,记录期望状态与已构建状态,生成不可变快照,计算精确变更集,再增量发布到文件系统或对象存储。
一句话概括:SOW 把“生成软件仓库索引”这件小事,和“治理一个长期运行的软件仓库”这件大事,装进了同一个单文件工具里。
这个工具纯粹是为了解决老冯自己的问题。但如果你也在维护大型、跨 Linux 发行版的软件仓库,它应该也能帮到你——虽然有这类需求的用户大概不会很多就是了。
为什么叫 SOW?
这个名字值得单独讲讲。此前,我们做过另一个配套开源项目:Pig —— PostgreSQL Install Genius;它是 PostgreSQL 生态的包管理器。既然有小猪负责装包,那么制作这些包、承载、组织与分发软件制品的仓库工具,自然就是“母猪” SOW 了。

它还可以展开为 Software Object Warehouse —— “软件对象仓库”。这个来自工业史的词,正好严丝合缝地落进软件供应链;更妙的是,它还有另一层双关:在传统铸铁场里,铁水先流入一条主槽,再分流到两侧的小槽里,冷却成一块块铁锭。那些铁锭叫 Pig,承载和分配铁水的主槽叫 Sow。从上方看,一条大槽带着一排小铁锭,正像一头母猪带着一窝小猪。

为什么要再造一个仓库工具?
最直接的诱因来自 Pigsty 的离线安装。Pigsty 会先把安装所需的 RPM / DEB 下载到本地,再生成一个离线软件仓库。过去,RPM 系统依赖 createrepo_c,Debian / Ubuntu 依赖 dpkg-dev。真正要生成的不过是几份 XML、Packages 与压缩索引,准备工具链却要装进几百 MB 的依赖。
这在 Linux 上已经够啰嗦;到了 macOS 上更难看。你得启动不同的 Linux 容器,挂载同一份目录,分别跑 RPM 与 DEB 工具,再把结果搬回来。为了生成几 MB 元数据,先请来几百 MB 工具链和一支容器车队,怎么看都不优雅。

到了 Pigsty 4.5,我把这套冗余清掉了。SOW 是一个几 MB 级的自包含二进制,在 Linux 和 macOS 上都能直接运行,同时理解 RPM / DEB 包格式与 APT / DNF 仓库规范。它没有守护进程,也不需要额外的语言运行时。
但“少装几个工具”只是表面问题。真正让我决定把 SOW 做下去的,是仓库规模扩大后暴露出的四个痛点。
第一,硬链接救不了对象存储
同一个 noarch RPM 可能同时出现在多个架构仓库里,同一份包也可能进入 beta、latest、stable 等多个视图。放在本地磁盘上,可以用硬链接让许多路径共用一份 inode;上传到 Cloudflare R2、OSS 或其他对象存储后,每个 object key 都会变成一份实打实的存储与上传成本。文件内容相同,不代表云端知道它们应该共享所有权。
第二,十万个文件让“比较一下”都变得昂贵
仓库更新通常只变动几十个包,但传统同步工具为了确认这一点,往往要把十几万个文件重新遍历、比较、校验一遍。全量检查一次花十几分钟并不稀奇;真正的数据传输可能只有几秒,时间全耗在“什么都没变”的证明上。

第三,在线仓库不应该露出半成品
一个 RPM 仓库不只是 .rpm 文件;客户端先读 repomd.xml,再沿着它找到 primary、filelists 和包体。APT 同理:Release、InRelease、Packages 与 by-hash 文件之间有严格引用关系。
如果更新顺序错了,客户端就可能先看到新指针,却找不到新指针引用的对象。对维护者来说只是几秒钟的上传窗口,对全球随机到访的用户来说,就是一次无法复现的 404、校验失败或安装中断。

第四,目录没有版本,发行版需要版本
最核心的问题是:当老冯想进一步改进仓库、提供 Channel 能力时,之前的维护模型就会遇到这些问题:如何同时维护 beta、latest、stable 仓库?如何每月保存一个快照?如何回答“上周三到底加了哪些包”?如何安全回退?哪些旧对象已经没有任何快照引用,可以删除?
这些需求单独看都能用脚本拼出来;组合到一起,脚本就会长成一套没有事务、没有模式、没有审计的影子数据库。市面上当然有 createrepo_c、dpkg-scanpackages、reprepro、aptly,也有通用同步与对象存储工具。但我没有找到一个足够轻、同时把 RPM 与 DEB、单份包池、不可变快照、原子发布和增量交付放进同一套清晰模型里的开源工具。
幸运的是,自己做工具的成本从来没有像现在这样低过。
两种复杂度,两种模式
SOW 并不假定所有仓库都需要同样的治理强度。它把问题切成 Plain 与 Managed 两层:小问题保持小,大问题才使用完整状态机。
Plain:包目录就是事实
Plain 模式只有一个核心命令:
目录里的 RPM / DEB 是唯一权威事实,repodata/、Packages 与 Packages.gz 都是可以随时丢弃重建的投影。SOW 会并行扫描顶层软件包,每个包在默认路径上只打开一次,在同一遍里完成 SHA-256、解析和渲染所需事实的提取,再生成两种仓库元数据。
生成结果先进入同文件系统的私有 staging 区,经过 SOW 自己的解析器校验后再替换公开文件。最后,它只重新比较文件集合与 stat 快照,确认构建期间没有包被新增、删除或替换;不会为了“再放心一次”把所有大包重新哈希一遍。

Plain 不保存操作日志,也不做沉重的事务恢复。进程中断了,就重新执行同一条 sow create:包目录还在,索引只是派生状态,重建比恢复更便宜。
--pigsty 模式还会最后写入 repo_complete 完成标记。只要这个标记不存在,消费方就知道这份仓库还没准备好。这是一个很小、但非常实用的提交协议。
这套模式解决了 Pigsty 最初的痛点:用一个小二进制替代两套工具链与多个容器,快速得到能被真实 APT / DNF / YUM 客户端消费的仓库。
Managed:仓库不是目录,而是状态机
长期运行的仓库不能只看“目录里现在有什么”。它还必须知道你 想要什么、上一次成功发布了什么,以及两者为什么不同。
SOW 的 Managed 模型分成四层:

Workspace 是配置与发现边界;Repository 是所有权边界;Dist 是一个具名的 RPM 或 DEB 成员集合;Architecture View 只是渲染结果,不再拥有一份软件包。这里最重要的不变式是:在一个 Repository 内,每个软件包只有一份正典包体,不留副本。
noarch RPM 或 all DEB 可以被投影进多个架构索引,却不会复制包体。beta 与 stable 也可以引用同一个软件包对象,而不制造第二份云端 object key。而且更妙的是,APT 和 DNF 仓库可以在同一套目录体系下管理。

“只存一份”的边界必须说准确:它是一个 Repository 或一个发布前缀,不是整个 Workspace、bucket 或全世界。不同 Repository 之间不做隐式去重,因为去重不能以破坏所有权为代价。删掉一个仓库,绝不能顺手删掉另一个仓库依赖的共享对象。
Desired、Built 与 Generation
Managed 模式把仓库状态拆成三个概念:
| 状态 | 含义 |
|---|---|
| Desired | 配置、加包、删包操作想要得到的成员集合 |
| Built | 上一次完整渲染、校验并提交成功的公共视图 |
| Generation | 对某个 Built 状态的不可变清单 |
这个区分看似学院派,实际上专门解决失败场景。
假设你一次加入五千个包,Desired 已经改变,但构建在中途被 SIGKILL。没有这层区分,系统只能面对一棵“不知道改到哪儿”的目录;有了它,SOW 可以诚实地说:意图已经更新,上一个 Built Generation 仍完整对外服务,新操作处于待恢复状态。
Generation 不是把整个仓库再复制一遍。它保存的是不可变 manifest、元数据与包体引用集合;多个快照可以引用同一份 Pool 对象。两代 Generation 之间的精确差异就是 Changeset:新增哪些包体、替换哪些元数据、切换哪些指针、哪些旧对象在保留期后可以删除,一目了然。
所以增量同步不再从“重新扫描十万个文件”开始,而是从“比较两个已知 Generation”开始。

原子切换的秘密:最后才动指针
软件仓库没有一个跨文件、跨对象的全局事务。SOW 的做法不是假装它存在,而是把发布顺序设计成可证明的协议:
先放入不可变包体;再写以 checksum 命名的元数据与 by-hash 索引;全部就位之后,最后才切换 repomd.xml、Release / InRelease 这些客户端入口。只有旧指针已经不再引用旧文件,并且保留期与证据门禁都满足,旧对象才允许删除。
因此,客户端沿着一个生效指针往下走时,它引用的内容一定已经存在。对单个协议视图来说,读者看到的要么是完整旧代,要么是完整新代,不会看到一棵被撕裂的树。
在本地 POSIX 文件系统上,这套过程依赖同盘 staging、fsync、原子 rename、稳定路径锁和持久操作日志。每条 Managed 写命令都会先检查并恢复上一次未完成操作,再开始自己的工作。恢复只根据已经落盘的证据判断该回滚还是前滚;证据矛盾时宁可中止并保持关闭状态,也不提供一个可能猜错的 repair --force。
对象存储不支持跨多个 Key 的原子提交,SOW 就先持久化 commit intent,再按确定顺序前滚协议指针,并为每个 target 单独保存 Applied Checkpoint。当前文件系统与 R2 发布各有自己的证据,前者成功绝不会被误认为后者也成功。R2 端如果缺少足够安全的条件删除证据,垃圾回收就只报告候选,不冒险远程删对象。
这也是 SOW 与一条 rclone sync 命令最本质的区别:传输文件不难,困难的是知道 哪些能传、何时算提交、失败后往哪边恢复,以及哪些真的可以删。
十万个对象,性能不能靠信仰
SOW 0.3 的主要工作,不是继续堆功能,而是把已经成立的模型推到真实仓库规模。
Plain 路径现在每个包只做一遍内容读取、哈希与解析,并通过 --jobs 使用有界并发。输入相同时,生成的元数据逐字节一致;无须更新时返回 no-op,也不会为了“更新一下时间戳”替换公开 inode。
Managed 路径则把解析后的“软件包事实”按不可变 SHA-256 缓存在 SQLite 中。新包入库时完整认证并解析一次;后续构建批量载入事实,在内存里完成成员投影。暖构建仍会遍历公开命名空间,但对未变化的 Pool 文件只检查 device、inode、size、mtime、ctime 指纹,不再把所有包体重新读一遍。指纹漂移时才回退到一次权威 SHA-256,并自动修复缓存;需要全量密码学审计时,显式运行 sow check。
这类优化的价值,必须落在数字上。
在项目基准中,一个包含 5,000 个对象的 Dist,成员展开从约 4.1 秒降到 33 毫秒;50,000 个对象原先十分钟仍跑不完,现在约 300 毫秒 完成。载荷提升也改成了有界单写入者组提交,每批最多 512 个对象或 1 GiB,既减少 fsync 风暴,也保证文件描述符和恢复状态不会随着仓库规模无限增长。
这些数字不是为了做一张跑分海报。它们只是说明:当仓库真的有十万个制品时,“状态模型正确”只是及格线,“日常小改动仍然足够便宜”才决定工具能不能被长期使用。
推倒第一版,再从最小闭环长回来
SOW 的开发时间不短,中间还经历过一次相当彻底的推倒重来。
最初那一版后来以 v0.1.0 留档。它野心很大:用 Git ref 管理仓库视图,用 SHA-256 CAS 保存制品,同时处理上游同步、多目标云发布、校验、修复、垃圾回收、Cloudflare Worker、CDN purge、边缘验证和生产迁移。
这些功能很多都已经做出来了,部分路径也通过了真实 APT / DNF 客户端与非生产 R2 环境的验收。但它的问题同样明显:仓库模型、云厂商、CDN、边缘运行时与迁移流程耦合得太紧。一项功能的正确性,要靠另外半套系统才能证明;任何小改动都会拖着一长串验收矩阵一起移动。
我最后决定把它封存。
推倒的不是目标,而是抵达目标的方式。一个基础设施工具最怕“什么都有一点,但没有哪一层能单独说清楚”。所以第二版先把最小闭环重新切出来:
- P0 / Plain Create: 一个目录进去,一个可用仓库出来;
- P1 / Managed Control Plane: Workspace、Repository、Dist、Membership、Build、Generation、Check、Changes 与 Operation Log;
- 更复杂的同步、远端发布、CDN 与供应商控制面,逐项回到独立验收队列。
v0.2.0 建立了今天的 Plain + Managed 主体:单份包池、元数据视图、确定性构建、锁、日志、崩溃恢复、Generation、文件系统与 R2 发布。
v0.3.0 没有再造一层概念,而是集中清理旧 V1 运行时,收敛云端传输边界,并解决 Plain 与 Managed 在大仓库上的重复读取、逐对象查询、载荷提交和可观察性问题。当前正式二进制只依赖新的 V2 核心,旧实现留在 Git 历史与 v0.1.0 / v0.2.0 标签里,作为经验,而不是第二套事实来源。
这条路看上去比“一次憋个大的”慢,其实更快。每一层都有独立契约、失败语义和真实客户端验收,下一层建立在已经站稳的地基上,而不是建立在一份越来越难读的愿望清单上。

接下来的 Roadmap
SOW 0.3 已经能创建仓库、管理成员与快照、计算变更集,并发布到文件系统和 R2;但它离我脑子里完整的软件制品控制面还有距离。
接下来主要有四条线:
- 上游仓库同步。 直接消费 APT / YUM 上游索引,验证签名与摘要,只拉取缺失制品,并把镜像结果纳入同一套 Package Object、Membership 与 Generation 模型。
- 更完整的增量交付。 现在
changes与 target checkpoint 已经能描述、复用并只发布差异;下一步是扩展对象存储与同步供应商覆盖,把大规模远端 inventory、断点恢复、条件写入和安全删除证据做成稳定闭环。 - CDN 与缓存控制。 CDN purge 不是“调一下 API”这么简单,还要绑定精确 Generation、缓存 TTL、回执与失败恢复。V1 已经证明这条路可行,但它会以独立、可验收的模块重新进入,而不是重新和仓库核心焊死。
- 版本与保留策略。 beta、latest、stable、月度快照这些需求,现在已经可以用 Dist、Generation、retain 与 target 组合表达;后续还会补上更高层的策略编排,让常见发布节奏不必由外部脚本手工串联。
这些能力在第一版里大多已经有过实现。我不打算把旧代码整块搬回来,而会像 0.2、0.3 一样,一次只拿回一个边界清楚、能独立验收的能力。
不再憋大招,持续交付小而完整的闭环。
猪猪家族还在继续长大
SOW 是 Pigsty “猪圈宇宙”的一部分,而且这个命名体系已经越来越离谱,也越来越完整:
- Pigsty:猪圈,负责安装和管理 PostgreSQL 生态;
- SOW:母猪,负责组织、构建和发布软件仓库;
- Boar:公猪,开发中的 PIGSTY GUI 管控平台;
- Silo:筒仓,负责 S3 兼容对象存储;
- Oink:猪叫,负责文档与网站框架;
- Snort:猪拱,负责收集日志与监控指标。
这当然首先是一套命名梗,但它背后也慢慢长出了一条完整链路:SOW 整理制品,Silo 存放制品,Pigsty 把它们安装成系统,Snort 观察系统,Oink 把一切讲清楚。而 SOW 填上的,正是过去最容易被忽视的那一段。
软件仓库看起来只是一个能被 Nginx 托管的目录,但当它承载十万个对象、多个操作系统、多个架构与无数用户之后,它其实是一台没有界面的数据库:有对象、有关系、有版本、有事务、有日志、有垃圾回收,还有绝不能写错的提交指针。
SOW 做的事情,就是把这些隐含规则变成显式模型,把一堆“祖传脚本应该没问题”的侥幸,变成可以检查、恢复和审计的工程契约。如果你只想建一个离线仓库,可以从一条命令开始:
如果你也在维护一套长期运行的软件发行版,欢迎访问 SOW 项目主页,或直接阅读 使用文档,看看它更深的一面。
SOW 采用 Apache-2.0 许可证。当前 v0.3.0 提供 Linux / macOS 的 amd64、arm64 归档,以及 Linux RPM / DEB 安装包;可以从 下载页获取,也可以直接查看 源代码。
十万个包并不可怕。可怕的是,它们还只是十万个文件。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
2 - 上游没有的 Bug,为什么会出现在官方包里?
老冯最近在 Pigsty 里面更新了 Redis 模块,把 Valkey 也打包进来作为一个可选引擎,结果在打包的过程中发现了一个上游的 BUG。 我给 Valkey 和 Debian 上游提交了修复,本文记录了这个过程。
内存炸裂
先看一个天文数字:18446744073709518664。
如果你的 Valkey 某天在 INFO memory 里报出这么一个数字,别怀疑服务器突然长出了 18 EB 内存。 这是一个 64 位无符号整数从零以下减穿之后,绕回来的结果。
在修复前发布的 Valkey 官方 DEB 包中,如果一次同步 SAVE 因为磁盘满、权限错误或者只读文件系统而失败,实例记录的 used_memory 就会悄悄减少一点。 失败次数足够多,计数器便会从零以下回绕到接近 2^64 的天文数字。
此时只要配置了 maxmemory,那些受内存上限检查约束的写命令就会开始返回 OOM。进程的实际 RSS 可能完全正常,日志里也没有什么明显线索,但 Valkey 坚信自己已经用掉了十几艾字节内存,直到重启才会恢复。
同一份补丁如果用在内置私有 jemalloc 的构建上,后果更干脆:第一次失败的同步存盘,就可能直接把进程打崩。
在 这个修复前,Valkey 7.2、8.0、8.1、9.0、9.1 五条官方 DEB 产品线,在 Debian 12、Debian 13、Ubuntu 22.04、Ubuntu 24.04 和两种 CPU 架构上都能复现。 RPM 没带这份补丁,所以不受影响;原始的 Valkey 上游源码也没有这个问题。
触发条件并不算宽。持久污染主要发生在主进程执行同步 SAVE 时;BGSAVE 和周期性存盘发生在子进程中,错误不会把主进程的内存一并改坏。 但这反而让它更阴险:它专挑你已经出事的时候,在旁边再点一把火。磁盘已经满了,快照已经失败了,监控或者备份脚本又在那里不断重试。 原本只是一次存储故障,最后却变成了内存统计穿越、业务写入 OOM,或者进程直接崩溃。
有趣的是:这不是 Valkey 内核里的 Bug —— 它是打包环节制造出来的。
雷不在上游源码里
Valkey 在 RDB 落盘失败时,会把当前工作目录打印到日志里。上游原版使用栈上的固定缓冲区,不需要做任何动态内存管理。
Debian 的打包补丁把它改成了堆分配:
动机非常正常:不要在栈上放一个固定大小的 4 KB 数组,也不要依赖 PATH_MAX。
问题在最后一行。
get_current_dir_name() 返回的内存遵循普通的 malloc() / free() 语义;zfree() 却是 Valkey 自己的内存释放接口。它并不是给 free() 换了个名字,而是会先向分配器查询这块内存有多大,再从 Valkey 自己的 used_memory 账本里扣掉这笔数字,最后才执行实际释放。
这块内存从来没有通过 Valkey 的 zmalloc() 分配,进账时没有记在 used_memory 里,出账时却照扣不误。
这不是一次普通的释放器错配,而是一笔 只出不进的假账。
至于它是静默记错账,还是当场崩溃,取决于 Packaging 阶段选择了哪套 jemalloc。
Valkey 官方 DEB 使用操作系统发行版提供的 jemalloc。它接管了全局的 malloc() 和 free(),所以这块指针至少仍然落在同一个实际分配器中,错误释放通常不会立即崩溃;但 zfree() 仍然会错误修改 Valkey 的内存统计。如果你选择直接从源码编译,、或者链接了内置 jemalloc 的版本,那更干脆:一次失败的 SAVE 直接段错误挂掉。
同一份补丁,因为链接方式不同,一个表现为悄悄腐蚀计数器,另一个表现为第一次失败就段错误。
这就是很多人容易忽略的一件事:用户实际运行的软件,并不只由上游源码决定。编译参数、依赖库和分配器选择,同样会改变程序的行为。Packaging 从来不是把源码塞进一个 .deb 文件那么简单。
它是对软件做的最后一次改写。
一条补丁绕了九年
顺着这份补丁的历史往回翻,它的血脉可以追到 2017 年。那一年,Debian 开发者 Chris Lamb 给 Debian 的 Redis 包写了一份补丁,用动态分配的 get_current_dir_name() 替代固定大小的工作目录缓冲区。
这是一项很正常的打包改进,最初也没有那行有问题的 zfree()。
2020 年,Redis 的这份补丁中出现了相同的释放器错配,并触发了崩溃。Redis Issue #7927 和 Debian Bug #972683 记录了几乎一样的调用栈,Debian 随后删除了那几处错误释放。
后来,Debian 从 Redis 的打包体系中派生出了 Valkey 打包,这份补丁也跟着迁了过去。在后续演化中,zfree(cwdp) 又一次出现在 Valkey 的补丁里。同一个错误,沿着同一条补丁血脉,隔了几年重新活了过来。
2025 年 3 月,Valkey 维护者 zuiderkwast 在研究系统 jemalloc 支持时,已经当场看出了问题:前面走的是普通 malloc(),后面却用 zfree(),这会搞乱 Valkey 的内存统计。这个判断完全正确。只是当时他的注意力放在 system jemalloc 上,所以结论停留在 “统计会出错”,没有继续发现:如果启用这个补丁换成内置私有 jemalloc 后,这条路径会直接 Seg Fault。
到了 2026 年 4 月,Valkey 建立了一套官方自动打包流水线,覆盖多条版本线、RPM 与 DEB,以及 40 个操作系统和架构组合。为了快速获得成熟的 DEB 打包能力,官方仓库把 Debian 的打包文件和补丁栈搬运了进来。于是,一个原本只存在于下游发行版中的补丁 Bug,沿着下面这条路线走了一圈:
Redis 上游 → Debian Redis → Debian Valkey → Valkey 官方发布仓库。
Valkey 官方不是从自己的主仓库中引入了一个 Bug,而是从 Debian 那里把自己原本没有的 Bug 搬了回来。官方发布的 DEB 包因此获得了一项上游源码并不具备的 “特色功能”。这是整件事最有黑色幽默感的地方。
开源世界通常是下游从上游拿源码,再打上一些自己的补丁。到了这里,官方项目为了发布 DEB,又反过来从下游把补丁整体抄回来。它复制了 Debian 多年积累的打包经验,也复制了 Debian 补丁栈里遗留的错误。
后来 zuiderkwast 在我的 PR 下面直接问了一句:
Why did we copy Debian’s patches?
这个问题比那一行 zfree() 更重要,因为真正需要解释的,已经不再是“这一行为什么写错”,而是:
为什么一份脱离上游主干、缺少原始上下文的下游补丁,会未经完整功能回归,重新进入官方发布链路?
测试一直在,只是测错了层
这颗雷最终能被翻出来,不靠什么高深的静态分析。
靠的是跑测试,而且是 codex 去跑测试。
我在给 Pigsty 重新梳理 Valkey 的 DEB 打包时,例行跑了一遍上游自带的 runtest。unit/shutdown 当场挂了三个用例,服务端留下了一份崩溃报告。Pigsty 的包使用内置 jemalloc,所以我们正好落在“第一次失败便直接崩溃”的分支上。症状比官方 DEB 剧烈得多,反而更容易定位。
顺着调用栈往上翻,最后就翻到了 debian/patches 下面那行 zfree(cwdp)。
而那个失败的测试,写得非常有针对性:它故意创建一个名为 dump.rdb 的目录,让最后的 rename(2) 必然失败,从而进入这条冷门错误路径。这个测试早就写好了。只要运行,就能抓住问题。
为了确认不是偶然现象,我又让 Codex 把不同 Valkey 版本、不同补丁状态、不同分配器和两种 CPU 架构组合起来,做了一轮交叉构建与复现。原始上游源码测试全过;应用错误补丁后稳定崩溃;把释放函数改正确后,测试再次全过。
问题在于,Valkey 官方的打包流水线没有运行这套上游测试。这里需要说得更准确一点:官方流水线并非“完全没有测试”。它会检查软件包能不能安装,二进制是否存在,systemd 服务能不能启动,安全加固、兼容符号链接和卸载流程是否正常。这些都是合格的 Packaging 测试,也很有必要。
但 Debian 打包规则中的 override_dh_auto_test 是一个空目标,真正运行 Valkey 上游回归测试的命令被注释掉了;那些被注释的命令后面,甚至还跟着一个吞掉错误的 || true。它测了包装盒是否完整,测了开箱后机器能不能通电,却没有运行机器自己的自检程序。于是出现了一个非常典型的质量接缝:
上游没有测到,因为上游源码里根本没有这份补丁;打包流水线没有测到,因为它没有运行上游功能测试。
这个 Bug 正好活在两套质量体系之间。上游 CI 是绿的,打包 CI 也是绿的,官方包照常发布。三件事可以同时成立,因为两边测试的根本不是同一份东西。
修复只有一行,问题不止一行
技术上的最小修复非常简单:把 zfree(cwdp) 换成 zlibc_free(cwdp)。
Valkey 专门提供了 zlibc_free(),用于释放不属于 Valkey 自己内存账本的分配。直接调用 free() 反而编译不过,因为 Valkey 有意把 free() 标记成 deprecated,构建又开启了 -Werror。
这也很可能解释了当初为什么有人会写出 zfree():作者试图修复一个真实的内存泄漏,先写 free(),被编译器挡了回来,于是换成了一个看起来最接近、又能通过编译的函数。
一个原本为了防止开发者绕过内存统计而设计的安全护栏,反过来把人推向了错误答案。
事情牵涉 Debian 和 Valkey 两边,我分别提交了 Bug 报告和上游 PR。给 Debian 报告时还被 Apple Mail 的富文本格式坑了一次:正文里的伪邮件头没有被 BTS 识别,第一封报告被系统整个忽略,切成纯文本才成功拿到 Bug 编号。
PR 很快获得批准,但 zuiderkwast 随后追问:既然这份补丁只是在一条冷门错误日志里避免使用 4 KB 栈数组,为什么还要保留它?这个问题问得对。我随后在 Pigsty 的 Valkey 和 Redis 包中直接删除了整份 Debian 打包补丁,重新构建并运行测试。用户可见行为没有变化,错误日志照常打印,测试全部通过,问题也随着补丁一起消失了。
这比把错误的 zfree() 换成正确的 zlibc_free() 更彻底。最安全的补丁,往往是根本不需要维护的补丁。
2026 年 8 月 7 日,修复 PR 被合并,五条版本线中的补丁副本全部得到修正。随后,维护者开始重新审视官方发布仓库中整套从 Debian 搬来的补丁。
但写到这里,这篇文章真正想讲的已经不只是 Valkey 了。
打包不是装箱
做 Pigsty 发行版越久,我越确信一件事:
打包不是把别人写好的软件装进纸箱,而是软件工程的最后一道生产工序。
用户最终运行的,从来不是 GitHub 上的那棵源码,而是下面这些东西共同组成的产物:
上游源码、下游补丁、编译器与编译参数、系统依赖、链接方式、默认配置、目录与权限、服务脚本、升级规则,以及最终到底跑了哪些测试。
一个软件包,实际上冻结了维护者对这些问题的全部判断。
好的打包可以弥补上游的不足:回补尚未进入稳定版本的修复,处理不同操作系统和依赖版本的兼容性,选择更稳妥的编译参数,修正默认配置,补齐服务管理、升级、回滚和安全加固。
坏的打包也可以反过来制造上游根本不存在的问题:补丁写错、编译参数改变语义、分配器换了一套、依赖库版本不匹配,或者干脆把最关键的测试跳了过去。
打包封装是最后一道质量防线
这起 Valkey 事故几乎把 Packaging 的作用演示得不能再清楚:
- 上游源码本身没有问题;
- 下游补丁引入了错误;
- 编译时选择哪种 jemalloc,决定错误是静默腐蚀还是直接崩溃;
- 官方发布流水线又把下游补丁复制到自己的包里;
- 包级安装测试通过了,上游功能测试却没有运行。
同一个项目、同一个版本号,仅仅因为打包方式不同,用户得到的就可能是三种完全不同的行为。
这也是发行版存在的意义。
Pigsty 现在维护着几百个扩展和组件,打包仓库中的 patch 有一百多个。它们有些用于修复上游缺陷,有些处理不同 PostgreSQL 版本、操作系统、编译器和系统库之间的兼容问题,还有一些只是为了让软件真正符合生产环境的目录、权限和运维约定。
我坐在同一个火山口上。
所以这件事对我不是一则可以站在旁边点评的开源趣闻,而是一次非常直接的警告:每一份 patch 都应该被当成生产代码来审查;每一个最终生成的软件包,都应该在真实目标环境中重新运行上游测试;每一种编译参数和依赖组合,都可能产生不同的行为。
我愿意把话说得更难听一点:
没有测试最终交付的软件包,就谈不上真正支持这个软件。最多只是把一个二进制文件放进了仓库。
发行版的质量,也不应该用“收录了多少组件”来衡量。
更重要的问题是:这些组件到底有没有在目标系统上被正确构建,有没有运行完整的回归测试,升级和降级是否安全,默认配置是否合理,出错时能不能恢复,维护者是否清楚每一份补丁为什么存在、何时可以删除。
上游项目提供的是原材料。发行版交付的才是用户真正运行的产品。
所有人都做对了自己的那一步
复盘整条链路,会发现这件事里没有一个特别愚蠢的反派。
2017 年写补丁的人,是想避免固定栈缓冲区;后来加释放的人,是想修复真实的内存泄漏;free() 被禁止,是为了防止开发者绕开 Valkey 的内存统计;2025 年的维护者一眼就看出了错配,只是低估了不同构建方式下的后果;官方发布流水线复用 Debian 补丁,也是因为 Debian 长期以来以打包质量著称。
每个人都在解决自己眼前的问题。每一步单独看,都有合理解释。凑在一起,却变成了一颗进入五条官方产品线的雷。
这种事故最麻烦的地方,就在于它不属于某一个明确的责任域。补丁不在上游主仓库的日常 Code Review 中,不在上游 CI 测试的源码树里,也不容易出现在普通用户查看的 git log 中。它从 Redis 复制到 Valkey,从 Debian 复制到 Valkey 官方,每复制一次,原始背景就少一点。
上游认为这是发行版自己的改动;发行版认为这是一份继承已久的成熟补丁;官方打包认为 Debian 已经替自己做过质量把关;用户最终拿到的是编译好的二进制,压根看不到里面打过什么 patch。
三方都默认有人看过。结果是谁也没有完整地看。所以真正的问题不在某一个人,而在那个没人完整负责的交界面。而 Packaging,恰恰长期处在这样的交界面上。
Agent 最该干的,不是再写一堆数据库
今年 PGConf 上,我做完 Extension for Everyone 的主题演讲之后,PGDG APT 仓库维护者 Christoph Berg 问了我一个非常实际的问题:这么多包,你都是怎么测试的?
这确实是发行版维护中最难回答的问题。
一个人不可能手工检查几百个组件、多个 PostgreSQL 大版本、多个 Linux 发行版和两种 CPU 架构,更不可能把每个软件的冷门错误路径、升级路径和异常场景全部走一遍。
我的回答是:除了项目自带的构建与回归测试,我会让 Codex 对最终软件包再做一轮冒烟和场景测试。按照用户真实使用这个软件的方式去安装、启动、连接、执行操作、制造错误,再观察它会不会在某个不起眼的地方露出问题。
这次的 Valkey Bug,就是这样翻出来的。测试是 Agent 跑的,交叉构建矩阵是它搭的,历史补丁是它追的,Debian 报告和 GitHub PR 是它起草的。后来我又让另一个 Agent 对调查结论做对抗性审查,它又找出了几处过度概括和事实错误。
这并不意味着 Agent 可以自动给出正确答案。恰恰相反,它第一次经常也不对。真正的价值在于:让它反复验证、推翻自己、重新编译、重新复现的成本,已经低到了人类很难做到的程度。
还有一个颇有黑色幽默感的细节:Valkey 官方打包流水线在合并之前,也使用 Claude 做过代码审查,找出了不少 GitHub Actions、安全性和构建稳健性问题;但那颗藏在补丁里的 allocator Bug 依然漏了过去。
这不说明 Claude 不行,也不说明 Codex更聪明。区别在于任务。一个 Agent 在看流水线代码,另一个 Agent 把最终软件包真的构建出来、安装起来、运行起来,然后故意把它弄坏。前者做的是 Review,后者做的是实验。
而软件工程最终相信的,应该是实验。
现在 AI 圈最热闹的用法,是让 Agent 去 vibe coding,或者宣布要重写 PostgreSQL、重写 Redis、重写操作系统。这样的故事听起来宏大,也很容易吸引眼球。但在基础设施领域,真正稀缺的往往不是更多代码。
缺的是验证。
让 Agent 再写一套数据库,最后只会给世界增加一套新的代码、补丁、依赖和供应链风险;让它把现有数据库在几个发行版、多个版本、两种架构上,把正常路径、错误路径、升级路径和边界条件一遍遍跑完,没那么性感,却更接近真实的工程价值。
人类不愿意为一个内存计数器搭十几份编译环境,不愿意跑几十遍崩溃复现,不愿意翻九年的补丁历史,也不愿意为了确认搜索结果可靠,再专门设计一组对照实验。
Agent 不嫌烦。
你只要给它一个清楚的目标,它可以把这些过去性价比极低、因此长期无人问津的质量工作做到底。
这才是 Agent 在测试和发行版工程中最值得期待的用途:
不是帮我们生产更多未经验证的代码,而是把已经准备交付给用户的代码,验证得更彻底。
与其让 Agent 再写一个数据库,不如先让它把你准备发出去的每一个包,认真跑一遍。
现在,至少不再缺有耐心的测试者了。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
3 - 瞬间克隆 PostgreSQL 数据库,无需黑魔法
老冯在半年前(2026-01-08)写过一篇文章《Git for Data:瞬间克隆 PG 数据库与实例》,介绍了 PostgreSQL 18 和 Pigsty v4.0 的一个新特性:瞬间克隆新数据库。利用文件系统 CoW 机制,以及 PG 18 的 file_copy_method = clone 新参数,可以在秒级克隆一个非常大的数据库,而且不占用额外的存储。
这玩意儿其实非常适合 AI Agent 使用。我在《Agent 需要什么样的数据库》里提到过:极低成本的数据库克隆对于反事实推演至关重要。所以当时趁着 4.0 上线的时候,给 Pigsty 里 PG 数据库 Provisioning 的地方加上了这个功能。
今天看到阿里云数据库 发了篇文章说,他们在阿里云 RDS for PostgreSQL 上支持这个功能了。老冯看了直想笑:这个动作也太慢了。说起来其实这个功能不复杂,不需要改内核,只要在 PG 18 上启用一个参数,在创建数据库的时候加一个 STRATEGY 参数就可以实现。说是不复杂,但想做好,还是有几个边界条件要处理。
一些改进
之前要克隆数据库的时候,在 Pigsty 的 IaC 式操作里还是有些繁琐:首先你要定义一个数据库,把另一个数据库作为模板,然后执行数据库创建。
所以这次我趁着 pig v1.5 发布的机会,把数据库克隆做成了一个简单易用的命令:pig pg clone。简单地说,现在你有个数据库 meta,只要执行 pig pg clone meta,它就会自动生成一个克隆。

当然,你可以使用参数来定制行为,比如指定分支的名字;如果不指定,就按下划线后加数字的方式依次自动起名。

命令会自动检测是否启用并支持瞬间克隆(目前用 Pigsty + XFS 就满足前提)。如果满足,就执行瞬间克隆;不满足,就警告、等待确认,并执行普通克隆。-y 可以跳过确认。
只要底层用的是支持 CoW 的文件系统(比如 XFS),那么克隆一个数据库基本是常数时间耗时,通常几百毫秒,而且占用空间不会变大;只有后续真实写脏的数据块,才会真正开始占用新的空间。
Agent Native CLI
当然,这个命令行工具的特点不一样:这是专门给 DBA 和 DBA Agent 设计的。之前你也可以用 Ansible Playbook,或者 Pigsty 提供的 Shell 脚本 /pg/bin/pg-clone 来执行克隆,但很显然都没有直接使用 pig 命令行工具方便。

比如,在执行操作之前,你可以使用 --plan 打印计划。它会告诉你会做什么事情、有什么风险。你还可以用 -o json 和 -o yaml 让它输出 JSON 和 YAML 格式的结果。

顺便一提,命令本体和 Help 输出也都可以使用 text、JSON、YAML 格式,因此 Agent 用起来会非常方便。因为它可以很轻松地用探索式方式,拿到所需的结构化帮助信息。pig 里所有命令都有这个功能。

这个设计,我之前称之为 Agent Native CLI,之前写了篇文章介绍过。
实例级 Fork
当然,除了 Database Clone,还有一个新的相关功能也值得一提。我在《Git for Data:瞬间克隆 PG 数据库与实例》里也提到过,就是实例级瞬间克隆,我将其称作 “fork”。

这里,你只要执行 pig pg fork dev,就能从当前实例创建一个名为 dev 的实例,随机分配一个新的端口号。这个功能在误删处理的时候非常实用:你可以先临时分支一个实例(不占用额外存储),然后快速用增量 PITR 回滚验证;验证无误之后,再在主实例上执行。
顺便一提,现在使用 pig 做 PITR 也非常方便。比如下面,一条龙傻瓜式执行时间点恢复到特定时间点,把时间点恢复的门槛压到了地板。当然,你也可以使用 pig pgbackrest 精准控制每一个操作。

这次 pig 命令行工具发布,新增了很多管理功能,包括对 PostgreSQL、Patroni、pgBackRest 组件的各种管理。现在它们都封装成上面 pg clone 与 pg fork 这类 Agent Native CLI,同时方便人类 DBA 与 AI Agent 使用。过几天会专门写篇文章详细介绍一下。

参考阅读
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
4 - 什么是 PostgreSQL 发行版?
经常有人问我:Pigsty 到底是什么?我通常回答:PostgreSQL 发行版。
通常下一个问题就是:那 “PostgreSQL 发行版” 又是什么?
这是个好问题。而要把它讲清楚,最好的切入点不是数据库,而是操作系统。
一、从 Linux 与操作系统发行版说起
说起 Distribution(发行版),绝大多数人第一反应都是 Linux 发行版 —— Red Hat、Debian、Ubuntu、SUSE、Arch…… 但问题是:既然已经有 Linux,为什么还需要 Linux 发行版?两者到底是什么关系?
答案很简单:Linus Torvalds 只写内核。
你把 Linux Kernel 编译出来,得到的不是一台能用的机器。你没有 Shell,没有 init 系统,没有 C 标准库,没有 coreutils,没有包管理器,没有网络工具,没有用户空间,也没有安全更新策略。内核负责调度硬件和提供系统调用,但它和 “一台能用的操作系统” 之间,隔着一整条工业化鸿沟。
这条鸿沟必须有人来填,而填的方式有无数种。用 glibc 还是 musl?用 systemd 还是 OpenRC?用 apt、dnf 还是 pacman?半年一版还是滚动更新?默认安全策略是什么?包怎么签名?漏洞怎么修?版本怎么维护?哪些服务默认启用 —— 这些选择叠在一起,才构成一个发行版。

所以,发行版交付的不是内核。发行版交付的是一整套集成决策,以及对这套决策长期负责的信用。
没有人会说 Debian、Red Hat、Ubuntu 是在和 Linus 竞争谁更会写内核。它们竞争的是另一件事:谁能把共享内核变成更可靠、更一致、更容易交付的系统。
内核是公地,发行版是工业化交付。真正的价值与竞争不在内核,而在发行版上。没有人去和 Linus 竞争 “谁写的内核更好”,但 Red Hat、Debian、Ubuntu 在 “如何把内核集成为一套可用系统” 这件事上,打了整整三十年。
这正是理解 PostgreSQL 发行版的钥匙。
二、搬到 PostgreSQL:相似,但不相同
PostgreSQL 可以说是数据库世界的 Linux 内核,但如果直接把 Linux 这套逻辑搬到 PostgreSQL 上,第一步就会撞墙。
PostgreSQL 不是 Linux Kernel。PostgreSQL 源码编译出来之后 initdb 一下就能跑。SQL 引擎、事务、MVCC、WAL、复制协议、psql、客户端库,核心能力都在。
PGDG 官方仓库也直接交付构建好的二进制制成品,用户直接安装拉起来就能用。
Linux 内核不能直接用,但 PostgreSQL 的内核是可以独立运行的。这就带来一个尖锐问题:既然 PostgreSQL 自己已经能跑,PG 发行版到底还要解决什么问题?

单机 PostgreSQL 是一个优秀的数据库内核。但生产系统要的不只是 “它能跑起来”,而是:主库挂了谁接管?备份坏了谁发现?误删数据能不能恢复到某个时间点?
连接池怎么切流量?证书怎么轮换?监控指标怎么采?告警怎么判定?扩展版本怎么管?参数漂移怎么拉回来?升级怎么做?新副本怎么补?故障恢复之后谁把系统收口?
这些都不是 initdb 和 yum install postgresql 能解决的问题。
PG 发行版的价值,就在这里。它不是把 PostgreSQL 变成可用的数据库系统(它本来就能用),而是把 PostgreSQL 内核集成为一套可生产运行的数据服务。
三、PG 发行版的三层工作
一个像样的 PG 发行版,至少要做好三件事:选择与集成、构建与分发、编排与管控。
这三层都重要,但它们的边际价值并不一样。越往后,越接近真正的战场。
1. 选择与集成:替用户做决定
生产 PostgreSQL 不是一个裸 postgres 进程。你要备份,要高可用,要连接池,要监控,要日志,要告警,要对象存储,要扩展,要权限模型,要默认参数 —— 每一个位置都有一堆选项。
备份可以用 pgBackRest、Barman、WAL-G,也可以用 pg_basebackup,甚至用 PG 备份原语手搓脚本。
高可用可以用 Patroni、repmgr、Pacemaker,甚至有人拿 PgPool 做主从切换。监控可以是 Prometheus、VictoriaMetrics、Grafana、Zabbix,随便排列组合都能拼出一套东西。

所以这里考验的是发行版作者的品味、经验和责任感。 所谓 opinionated,不是拍脑袋替用户做主,而是你踩过足够多的坑,知道哪些路是正确的、更优的。
不过平心而论,这一层的价值正在收敛。好东西用久了,社区会形成共识:高可用越来越绕不开 Patroni,备份越来越绕不开 pgBackRest,监控越来越绕不开 Prometheus / Grafana 这类组合。 选型仍然重要,但单靠 “我选了正确组件” 已经很难形成护城河。
光会选型还不够,还要能可靠地交付。
2. 构建与分发:供应链是信任,不是噱头
第二层是构建与分发。这层经常被低估,因为用户只看到一个包名,很少看见后面那堆脏活:多系统、多架构、多版本、多扩展、依赖解析、ABI 兼容、GPG 签名、CVE 响应、仓库可用性、版本生命周期。
PGDG 已经做了一块很强的公共基础设施。PGDG 提供了 YUM 和 APT 仓库,提供预制的 PostgreSQL 内核、一百多个扩展,和一些关键的生态组件 —— 这是一块极好的公地。
也正因为这块公地已经很好,你要在构建分发层做出差异,就必须提供额外增量。比如 Pigsty 自己的仓库补齐了大量 PostgreSQL 扩展(额外的 300 个)和基础设施软件包,在 16 个 Linux 操作系统上提供原生的 RPM / DEB 包,已经持续维护了快四年。

打包背后的长期可信、快速修补、稳定供应链,以及长时间维护积累的可靠性战绩与历史信用,确实是一种壁垒,而且随时间沉淀累积。但这是一种守成能力:它能让用户放心把生产系统放在你的仓库上,却很难单独解释为什么用户非你不可。
真正把发行版和 “装包脚本” 拉开差距的,是下一层 —— 编排与管控。
3. 编排与管控:把静态包变成活系统
发行版中真正的硬骨头,其实是编排与管控。选型品味在收敛,构建分发只能守成,而编排与管控,是所有玩家真刀真枪见高下的地方。它的难点,一句话就能说清:如何让这些 “静态的包”,变成 “动态运行的服务”?
打个比方:软件仓库只负责给你面粉、鸡蛋和黄油,但如何把它们烹饪成一个蛋糕,仓库是不管的。哪怕再随包附赠一份详尽的食谱(也就是文档),离一个真正出炉的成品蛋糕,也还差着十万八千里 —— 更别提有的生产系统其实要的甚至是自动生产蛋糕的流水线了。
许多老牌开源发行版和云上 RDS 之间的差距,恰恰就落在这最后一步。 前者给你一堆装好的包,后者卖给你一个开箱即用、自动运维、故障自愈的服务。中间隔着的,正是 “编排” 这道谁都替代不了的工序。
这个 “烹饪” 的动作,就是编排(Orchestrating)—— 把一个静态的、类似 DVD 光盘介质的东西,变成一个运行时的、动态的、活的系统。它要操心的,全是 initdb 之后 PG 内核撒手不管、仓库也从不负责的那些事:一堆组件按什么顺序拉起、谁依赖谁;主库挂了怎么自动检测、选主、切流量、让连接池重连、把新副本补齐 —— 这一整条故障自愈的闭环;以及最关键的,如何让整个系统始终维持在你声明的那个目标状态,一旦漂移就自动拉回来。

编排与管控这一维之所以是护城河,恰恰因为它 没有公地。没人替你把 “面粉鸡蛋” 变成 “蛋糕”,这活儿只能各家自己干,干得好坏,差距高下立判。
四、编排的两条路:K8s 原生与 Linux 原生
既然关键是编排,那么问题就变成:你把这套控制平面放在哪一层?
主流的答案有两条,它们构成了今天 PG 发行版最主要的两条赛道。分野的实质是 你选择在哪一层实现编排与管控:一条基于 Kubernetes 提供的公共底座,一条回到 Linux 操作系统本身从头构建。这两条路没有绝对的优劣,只有不同的利弊权衡。
赛道一:Kubernetes(云原生)
这条路把数据库当作 Kubernetes 上的一等公民,用 Operator 模式来编排。你写一份声明式的 CRD,Operator 通过它的控制器循环(reconcile loop),持续地把集群的现实状态收敛到你声明的目标状态 —— 拉起、监控、故障切换、扩缩容,都在 K8s 这一层完成。
这是目前 最拥挤、也最热闹 的赛道,玩家云集:CloudNativePG(EDB 主导,约 8900 Star,如今最主流的 PG Operator)、Zalando Postgres Operator(约 5200 Star)、Crunchy PGO(约 4400 Star)、KubeBlocks(约 3100 Star),以及 StackGres、Kubegres、Tembo、KubeDB、Percona Operator 等一长串。
这条路的优点很清楚:统一控制平面,声明式 API,GitOps 友好,平台团队容易接入。对那些已经把 Kubernetes 作为组织级操作系统的团队来说,数据库上 K8s 是自然延伸。
但代价也同样清楚:你不只是引入一个 PG Operator,你是在引入 Kubernetes 这整套控制平面、存储抽象、网络抽象、调度模型、权限模型、故障模型和心智负担。这条路真正的门槛,不在 Operator 本身,而在你是否已经为 Kubernetes 付过了那笔学费。

赛道二:Linux 原生(原生操作系统)
这条路不把数据库塞进 Kubernetes,而是回到操作系统本身:直接跑在 Linux 上,运行于物理机或虚拟机环境,安装 RPM / DEB 包,通过 systemd 管理服务,使用 Ansible 或者类似的 IaC 工具发起管理。
这条赛道的开源玩家要少一些:Pigsty(约 5200 Star)、Autobase(约 4300 Star)、pgEdge(约 700 Star)、EDB TPA(约 90 Star)。此外还站着一整排没有公开 Star、但在企业市场分量十足的 商业发行版:EDB Postgres Advanced Server(EDB 旗舰,堪称 PG 世界的 Red Hat)、Percona Distribution、CYBERTEC PGEE、ClusterControl 等等。
这条路的优点是路径短,依赖少,离数据库本体更近,中间没有额外的抽象层,故障域更小,行为更可预测,也更容易被 DBA 直接理解和接管。它的代价则是:没有 K8s 替你处理状态收敛、幂等执行、故障恢复、升级编排,你得自己想办法实现,还要直面十几种主流发行版大版本之间的差异 —— 这是一份持续的、并不性感的苦役。
Pigsty 的选择
两条路各有其合理性,选择哪条取决于你的团队已经站在哪里、把复杂度放在哪里更划算。Pigsty 选择了 Linux 原生这条道路,理由我在《数据库是否应该放入 K8S 中》和《容器化数据库是个好主意吗?》里已经充分阐述过了 —— 我认为对于数据库来说,这是一条更贴合本质、艰难但正确的道路。
也正是在这条艰难的路上 —— Pigsty 跑在了前沿。如果看开源影响力,它已经是 Linux 原生这一侧的第一名(5200 Star,领先于同赛道的 Autobase ~4300);放到包含 K8s 赛道在内的整个 PG 发行版版图里,它是第二名,仅次于 EDB 发起的 CloudNativePG。

今天你若问主流 AI 模型 “我要在 Linux 上自建企业级 PostgreSQL 服务”,Pigsty 基本已是首选推荐。对一个由独立开发者主导、不依附任何云厂商的项目来说,能走到这一步,确实不容易。
五、再往前一步:Meta Distribution
到这里,故事本可以收尾了。但 Pigsty 还做了一件更有意思的事,触及了 “PG 发行版” 这个词的边界。
业界有一个默认假设:一个发行版围绕某一个固定内核来构建。 Debian / RedHat 围绕 Linux,传统 PG 发行版围绕原生 PostgreSQL 内核构建,发行版和它的内核几乎是绑定的。
但 PostgreSQL 世界里有一批特殊存在:OrioleDB 换了存储引擎,Babelfish 做 SQL Server 协议兼容,PolarDB PG 做了 RAC,IvorySQL 兼容 Oracle 语法,还有兼容 MySQL 的 openHalo、提供透明加密的 Percona TDE 等等。它们改了 PG 内核,严格说已不再是 “纯 PostgreSQL”,而是 PG 兼容家族里的不同物种与亚种。按传统做法,每一个亚种都得各自造一套运维体系。
Pigsty 选择的是另一条路:把编排与管控的底盘抽出来,让内核本身成为可替换层。 这其实是前面第三层工作做到一定程度后的自然结果 —— 一旦你的控制平面足够灵活,不再和某个具体内核绑死,给它换一颗内核,就只是换一份构建产物和配置模板的事。我们为这些不同风味的 PG Fork 构建了二进制包并提供配置模板,让用户在同一套底座上运行不同内核,目前支持的内核已达 12+。
在这个意义上,它已不只是一个 “PostgreSQL 发行版”。你可以用它裁剪出自己的发行版 —— IvorySQL 发行版、PolarDB 发行版、TDE 发行版;甚至通过组合模块,让它摇身变成 Redis、Etcd、MinIO 的发行版,或是 Prometheus / VictoriaMetrics 乃至 Claude Code 与 Codex 的发行版。

所以,更准确地说,它是一个 Meta Distribution,发行版的发行版。而一套能被这样反复裁剪、复用、再分发的底盘,本身就是一种可以被传递出去的能力 —— 它不再属于某一个内核,也不再只属于某一个人。
尾声:发行版是一条信任的供应链
绕回最初的问题:什么是 PostgreSQL 发行版?
如果只从技术上拆,它有三项核心工作:选型与集成替你做对了决定,构建与分发把这些决定的产物送到你面前,编排与管控再把静态的包变成一个活的、自愈的系统。
但一个发行版真正的灵魂,其实在这三层技术之下。
因为技术是可以被复制的。选型可以抄,包可以照着打,编排的思路,只要有人肯花时间,也总能复刻个七八分。真正无法被复制、也决定了一个发行版能否被长期托付的,是两样东西:一个持续使用它、维护它的社区,和由此一点点长出来的信任。
因为用户真正需要的,从来不只是 “我该装哪个包”,而是:我信谁的包?信谁的默认参数?信谁的扩展构建?信谁的高可用判断?信谁的备份恢复流程?信谁在 CVE 出来后第一时间修补?信谁在五年之后仍然维护这条路线?信谁在系统漂移、故障切换、版本升级、数据恢复这些最要命的时刻,仍然能把整个系统收回来?
这一连串问句的答案,指向的都不是某段代码,而是 代码背后那个持续负责的人和社区。所谓发行版的本质,就是把散落在源码、构建、签名、仓库、扩展、配置、编排、监控、升级、故障恢复之间的责任,收束成一条可验证、可复现、可审计、可长期托付的信任供应链 —— 而信任,正是从这条链上一次次兑现的承诺里,一点点沉淀出来的。它买不来,也抄不走,只能靠一个社区用时间去长。

云服务当然也提供信任,只不过它把整条链条藏进了黑盒。你买到的是托管信任,但同时也交出了透明度、可迁移性和最终控制权。你相信云厂商会替你选对组件、打好补丁、做好备份、处理故障、规划升级,也相信它不会反过来在价格、权限、生态、合规、可用性上卡住你。这是一种信任,只是它的代价,是你不再看得见、也不再能自己接管这条链。
Pigsty 选择的是另一条路:不把复杂度神秘化,不把责任外包给不可见的控制平面,而是把这条链摊开、固化、签名、编排,并尽可能交还给用户自己掌控。所以它不是一个 “装 PostgreSQL 的工具”,也不只是一个 “自建 RDS 脚本”。它想交付的,是一套 开放的 PostgreSQL 信任供应链:从上游内核到扩展制品,从 RPM / DEB 仓库到高可用编排,从监控告警到备份恢复,从单一 PG 内核到整个 PG 兼容内核家族 —— 每一环都可核验,每一环都可接管,背后都有一个愿意长期维护它的社区。
Linux 发行版当年真正沉淀下来的,从来不只是把内核集成成系统的技术,而是 Debian、Red Hat 这些名字背后,几十年如一日 “一直有人在” 所积累起来的信用。Pigsty 想在 PostgreSQL 世界里长出的,正是这样一份信任 —— 并且让它是开放的、可审计的、可以自己接管的。
真正的发行版,最后交付的从来不是软件,而是一条可以被审计、被复现、被迁移、被长期托付的信任供应链,以及背后那个为它负责的社区。
不租云,不拜神,不把复杂度 —— 也不把信任 —— 放进任何人的黑盒子里。
而是把运行顶级生产数据库服务的能力,连同那个愿意为它长期负责的社区,一起交还给愿意自己运行它的用户。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
5 - 人人可用的 PG 扩展
在线幻灯片:人人都能用上的 PostgreSQL 扩展
第一部分:引言
0. 人人都能用上的扩展
大家好,这次演讲的题目是「人人都能用上的扩展」。
它讨论的是 PostgreSQL 扩展的交付,以及一个共享的交付层,如何同时让用户、扩展作者、厂商和 PostgreSQL 内核开发者受益。
1. 我是谁
我是冯若航,Pigsty 的作者和维护者。Pigsty 是一个开源 PostgreSQL 发行版。
我也是 pgext.cloud 的建设者。pgext.cloud 是一个面向 PostgreSQL 扩展的开源交付层。
过去两年里,我一直在为数百个扩展做编目、构建、打包和测试,覆盖不同 PostgreSQL 版本和 Linux 平台。所以这次分享不是理论推演,而是一份一线报告。
2. 可扩展性很重要
可扩展性很重要。两年前,我写过一篇文章,说 PostgreSQL 正在吞噬数据库世界。
当时的论点很简单:PostgreSQL 的成功源自可扩展性。它允许生态快速前进,而不必把每一个新想法都塞进内核。这是 PostgreSQL 的超能力。但它也带来了一个很现实的问题。
如果 PostgreSQL 是通过扩展来成长的,那么扩展交付本身就成了系统的一部分。
只有可扩展性还不够。一个扩展只有在能被发现、能被安装、能被信任时,才真正有意义。
这就是我开始收集和打包扩展的原因。
3. 两年之后
两年之后,我已经搭建了一套面向 PG 扩展的开源基础设施,叫 pgext.cloud。
今天,它覆盖 16 个 Linux 目标平台和 5 个活跃的 PostgreSQL 大版本。加上 PGDG 和 contrib,可交付的扩展集合大约有 511 个。
这个仓库每月提供大约一百万次下载。现在已有几家 PostgreSQL 厂商通过它交付自己的扩展。但这次演讲的重点并不是这个仓库本身。
真正重要的是,我们在维护这张矩阵时学到了什么。这才是我今天想分享的内容。
4. 谁会受益?
我说「人人都能用上的扩展」时,指的是四类人。
第一类是用户和 DBA。他们想要的是包,而不是在生产服务器上编译代码。
第二类是扩展作者。他们需要触达用户,也不想被构建和交付这些琐事拖住。
第三类是厂商。他们需要可复用的组件。反复重建同一批包,是对工程时间的浪费。
第四类是 PostgreSQL 内核开发者。他们需要信号。当兼容性被破坏时,扩展往往是最早暴露问题的地方。
所以这件事本质上是一个共享交付层。它不只是为了方便,也提供了可见性。在谈交付之前,我们先看一下生态本身。我们需要先理解,我们到底要交付什么。
第二部分:生态全景
5. 星系
PostgreSQL 到底有多少扩展?社区里有一个很有名的、由大家共同维护的 GitHub 列表,里面有一千多个条目。我维护的目录目前跟踪了大约 1,617 个条目。
但这个数字需要放在上下文里看。
有些项目仍然活跃,有些已经废弃;有些只能在云上使用;有些依赖专门的 PostgreSQL 分叉;还有一些只是想法和示例。所以,1,617 并不意味着有 1,617 个可以直接安装的扩展。
它意味着生态的边界很大,而且很乱。
6. GitHub 星标
第一个公开信号是 GitHub 星标。星标不能衡量质量,也不能衡量生产使用情况,而且会漏掉那些根本不托管在 GitHub 上的项目,比如 postgres 和 postgis。
但星标仍然有用。它反映了关注度、声誉和大致的认知度。排在前面的都是熟悉的名字:TimescaleDB、pgvector、Citus、pg_search、pgml、pgai、pgmq,还有很多其他项目。
如果观察分布,会发现它极度倾斜。少数扩展拿走了大部分关注度,后面是一条长尾。这是一个对数分布。
7. 星标分层
按数量级给扩展分组,就会得到一个简单的分层模型。
第零层:四大天王。PostGIS、TimescaleDB、pgvector、Citus,每个都超过一万星。
第一层:44 个扩展,星标在一千到一万之间。
第二层:大约 152 个扩展,超过一百星。
第三层:大约 373 个扩展,超过十星。
然后是约 748 个低于十星的长尾扩展。
这不是质量排名。有些热门项目已经不再活跃,比如 pgml 或 zombodb。有些低星扩展反而非常有用。
但这些层级说明了一件事:可见的生态要比被发现的生态小得多。把第零层到第三层加起来,大约是 570 个超过十星的扩展,和实际可交付的规模很接近。
8. 扩展漏斗
于是我们得到了一个漏斗。顶部有 1,600 个候选项。如果砍掉长尾,数量会迅速下降。
中间大约有 500 个已经被编目、打包和交付。
按来源拆开看,大约 330 个来自 Pigsty 仓库,160 个来自 PGDG,两边还有一些重叠。最底部,是 PostgreSQL 自带的 71 个 contrib 扩展。
关键在于这个形状。发现面很宽,交付范围窄一些,实际使用又更窄。
9. 维度分析
这个目录还跟踪星标之外的很多维度:语言、许可证、分类、最近发布日期、仓库状态、打包状态、PG 版本支持、操作系统支持。这里可以浏览 32 个不同维度。
现在,我们从「存在什么」转向「什么真的可以被交付」。
第三部分:交付层
10. 现状
打包 PostgreSQL 扩展很难。难点不是包格式有多神秘,而是矩阵太大。我们面对的是 5 个活跃 PG 大版本乘以 16 个 Linux 平台,也就是每个扩展 80 个构建槽位。真正覆盖全部槽位的扩展只有少数。
Christoph 和 Devrim 维护的 PGDG YUM 与 APT 仓库已经完成了基础工作。它们承载了许多最重要的扩展,总共大约 150 个包。但缺口仍然存在,比如 Rust 扩展,以及一些没有被覆盖的操作系统和 PG 组合。
所以这个互补仓库的目标,就是补上这些缺口。在 PGDG 覆盖不到的地方,或者构建成本太高、难以维护的地方,额外交付包。总体上大约新增 300 个扩展包。
11. 取舍
这背后有一个真实的取舍。C 扩展构建得很快,Rust 扩展则不是。一个 Rust 扩展的构建时间,可能比所有 C 扩展加起来还长。
但用户仍然需要它们。比如自托管的 Supabase 栈大约需要十几个扩展,其中三个是 Rust 扩展。所以问题不是这件事有没有必要,而是这项工作应该放在哪里完成。
12. 为什么要做 Linux 原生包?
容器镜像可以减少一部分矩阵。这一点我非常认可。有了容器,每个扩展只需要构建 5 个 PG 大版本乘以 2 个架构,也就是 10 个槽位,规模缩小了 8 倍。
但 Linux 原生包仍然很重要。很多用户仍然通过系统原生包管理器安装 Postgres,也就是 APT 或 YUM。而且大多数 Postgres Docker 镜像本身,也是从 PGDG APT 仓库安装 Debian 包形式的扩展。
所以,这些打包工作总要有人来做。
13. 基础设施
为了把这些 RPM 和 DEB 扩展包交付给用户,我们围绕它搭建了一套开源基础设施。它有四个部分:用于发现的目录,用于交付的仓库,一个可选的 CLI,用来简化访问。
在它们背后,是构建矩阵。CLI 很简单,仓库很有用,但目录和构建矩阵才是大部分工程成本所在。
14. 扩展目录
目录是事实来源。它不是一个营销页面,而是一个带结构化元数据的数据库,描述扩展的一切:维度、标签、依赖、可用性矩阵,以及如何安装、配置、构建和使用的备注。
这听起来像是枯燥的脏活。但正是这些枯燥的元数据,让系统的其他部分能够可预测地运行。有了这些数据,你甚至可以让 Codex 用一句提示词重新生成扩展星系图。
15. 目录细节
目录是交付路径的一部分。网站和 CLI 工具都把它作为事实来源。
目前这些元数据会定期导出为几个 CSV 文件。它有两个版本:一个 universe 版本,收集 1,600 个扩展的通用元数据;一个详细版本,覆盖其中 511 个扩展。
如果有一天,这类信息能放到 postgresql.org 上,成为官方扩展目录,我会非常高兴。现在它暂时放在 pgext.cloud 和 GitHub 上。
16. 目录页访问量
目录网站也会给出页面访问量数据。它不等同于生产使用量,但能告诉我们用户在看什么。这很有用。它能告诉我们哪些扩展值得优先投入打包精力,哪些类别正在活跃起来。
这里是过去一个月的扩展页面访问量数据。
17. 仓库
要把这些扩展交付给用户,只有目录还不够。还需要一个仓库。
从技术上说,这个仓库是一个 APT 与 YUM 仓库,提供签名的 Linux 原生包,托管在 Cloudflare 上,并带有区域镜像。
这个仓库的目标是增强 PGDG 的 YUM 和 APT 仓库。它完全兼容 PGDG,遵循同样的约定,使用用户已经理解和熟悉的包布局。
18. 仓库下载统计
这个仓库现在每月大约提供一百万次 RPM 和 DEB 下载。
但这些数字有局限。它们不包括 PGDG 那一侧的数据。而 Cloudflare 在企业版之外不提供详细访问日志,所以我们缺失了很多数据。
如果 PGDG 仓库能够共享访问日志,或者至少提供一些聚合统计,我会非常欢迎。那会成为扩展生态里非常有价值的信号。
19. 我们仍然可以推断什么
即便下载数据是局部的、有偏的,它仍然有用。它可以显示哪些 PG 大版本仍然活跃,哪些操作系统目标重要,也可以显示某个包组合是否有足够使用量,值得继续维护。
但要小心。下载量少的包仍然可能很重要。也许我们需要一个综合信号,把星标、页面访问量、可用性、构建失败和下载量结合起来,形成类似 DB-Engines 风格的 PostgreSQL 扩展评分。
20. CLI:PIG
有了目录和仓库,扩展交付基本上就解决了。你可以直接使用系统包管理器,从 PGDG 和 PGEXT 仓库安装扩展,比如 dnf 或 apt。
我们还有一个专用但完全可选的命令行工具,叫 PIG。它用 Go 编写,只有 4 MB。这个名字的含义是「piggyback on the OS package manager」,也就是借力系统包管理器。它会隐藏所有复杂度,让用户直接完成安装。
有意思的是,它不只是能安装,也能构建和交付二进制包。如果你想要 pg_search 或 pg_duckdb,只要运行 pig build pkg pg_search,它就会帮你构建包。
这对供应链信任很重要。用户愿意的话,可以自行重建所有东西。
这就是交付层:目录、仓库、CLI,以及它们背后的构建矩阵。纸面上看起来很清晰。但在实践中,矩阵才是真正困难的地方。
第四部分:野外维护
21. 扩展矩阵
上一章我们谈到了矩阵:每个扩展 80 个槽位。
但 5 个 PG 版本乘以 16 个 Linux 平台,只是一个过度简化的模型。真实情况要混乱得多。它包含的因素远不止行和列。
在操作系统侧,有发行版家族、架构、大版本,有时还有小版本。
在 PG 侧,有大版本,有时也有小版本。
在扩展侧,有扩展版本;对于 Rust 扩展,还有 pgrx 版本。
把这些因素相乘,组合数量会非常快地爆炸。
本部分接下来要讨论的,就是这种爆炸式复杂度撞上现实之后,我们学到了什么。
22. PG 小版本 ABI 破坏
去年我们遇到过一个案例。PG 17.1 在小版本升级中破坏了 ABI,导致包括 TimescaleDB 在内的一些扩展出问题。
作为回应,一些维护者转向为每一个 PG 小版本构建。但这又会制造新的问题。如果每个小版本都单独构建,原地升级就会变得困难得多。
更好的办法是把它当作例外情况处理。但当它真的发生时,我们必须做好准备。
23. 操作系统小版本破坏
有时候,即使是操作系统的小版本也会破坏构建。
例如,EL 把 OpenSSL 版本从 3.2 升到 3.5,一些扩展会在链接阶段失败。
作为回应,PGDG YUM 仓库最近修改了打包策略,从按大版本构建改为按小版本构建。所以现在我们有了 EL 10.0、10.1、9.6、9.7 的独立构建,而不只是 EL 10 和 EL 9。这又给矩阵增加了一个子维度。
24. Rust 问题
Rust 扩展正在增长。它们给生态带来了新的人和新的想法。Rust 社区使用一个叫 pgrx 的框架来编写这些扩展,而这又引入了几个新问题。
第一是构建成本。Rust 构建很慢,也很吃磁盘。一个 Rust 扩展的构建时间,可能比所有 C 扩展加起来还长。
第二是 pgrx 自身也有版本,比如 0.16、0.17、0.18,而且它们并不能互换。我花了很多时间把 Rust 扩展对齐到特定的 pgrx 版本上,但随着时间推移,版本漂移又会回来。
所以 Rust 不只是增加了一门语言。它还增加了一条兼容性维度。
25. 臃肿的扩展
过去扩展通常很小,典型大小只有几百 KB。现在不总是这样了。
一些新的扩展,比如 pg_search 和 pg_duckdb,体积有几十 MB。源码归档和构建产物都会迅速膨胀。放到完整矩阵里,这会变成真实的存储和带宽成本。
26. 命名冲突
矩阵是一类复杂性,扩展之间的冲突是另一类。
去年,我讲过 Citus 和 Hydra 争夺同一个名字 columnar 的问题。今年我们又有了一个新例子:bm25。现在有三个扩展暴露了名为 bm25 的访问方法:
- ParadeDB 的 pg_search
- Timescale 的 pg_textsearch
- TensorChord 的 vchord_bm25
和 Citus 与 Hydra 不同,这三个扩展可以一起安装。但你不能在同一个数据库里把它们全都创建出来,因为访问方法名称会冲突。
这不只是一个打包问题,而是生态元数据问题。如果目录记录的不只是包名,还包括扩展对象、库和访问方法,作者就可以在发布前检查冲突。
27. 库冲突
另一个例子是,三个基于 DuckDB 的扩展都想使用同一个共享库:libduckdb。
包管理器看到的是磁盘上的文件。PostgreSQL 看到的是共享库和 control 文件。用户看到的是 CREATE EXTENSION。这三层的理解可能互相不一致。
实际解决方案,是把其中两个扩展作为 pg_duckdb 下面的子扩展挂载起来。这个方案能工作,但协调和说服作者花了真实的精力。
教训很简单:名字也是兼容性的一部分,而且名字真的会冲突。
28. API 破坏
我们也修复了很多缺乏活跃维护的扩展。有些扩展距离上一次发布已经过去多年。但 PostgreSQL 大版本变化仍然会影响它们。
通常,原作者会编写不同版本分支来处理不同 PG 大版本。如果扩展已经不再维护,打包者就必须接手。
前面我们讲过,这项工作如何帮助前三类人:用户、作者和厂商。那它对 PostgreSQL 内核开发者是否也有用?
我认为,构建覆盖率是一种有用信号。当一个补丁破坏了 N 个扩展时,这个数字本身就是信息。它显示了生态影响。这时,交付基础设施就开始变成反馈基础设施。
29. PG 19 兼容性
一个具体案例是,我用 PostgreSQL 19 的开发快照跑了一遍构建流水线。大约 50 个扩展构建失败。
这些失败集中在少数几类:真正的 API 变化、过时的假设、缺少版本分支、依赖问题,以及原本就已经很脆弱的包。
去年有些内核开发者告诉我,这对影响面很广的补丁可能有用,比如线程化工作、重构、hook 变化。如果 CI 流水线能针对某个补丁系列运行扩展构建,那么结果就可以成为补丁评审过程中的有用输入。
我很想听听在座各位的反馈:这件事值不值得继续推进?目标是让生态影响更早可见。
30. 让它可维护
一个现实问题是可维护性。所有这些工作都是一个人在做。我经营着一家一人公司,也维护着一个一人发行版 Pigsty。这件事我已经做了大约五年。
最近它变得容易了一些,原因是 AI 工具。去年,每一个构建 spec 都是手写的。积累了足够多的示例之后,添加新扩展已经变得很直接。上个月我在两天内新增了 50 个扩展。
我的朋友 Yurii Rashkovskii 曾经描述过一个叫 PGPM 的想法:URL in, RPM out。给一个 URL,吐出一个 RPM。有了 Codex 和 Claude Code,这个想法正在变成现实。
AI 也降低了测试成本。我们可以从扩展文档驱动冒烟检查,更早捕获行为回归。AI 可能还没准备好提交 Postgres 内核补丁。但它显然足够胜任这类工作。我维护了一个 MinIO 分叉,用来修复 CVE 和 bug,几乎完全依靠 Codex 和 Claude Code。它真的跑在生产环境里。
这是一个维护者让 511 个扩展组成的矩阵继续活下去的办法。
31. 三个问题
最后,扩展是 Postgres 生态的共同财富。我希望这项工作能帮助用户、作者、厂商和 Postgres 内核开发者,一起建设更好的 Postgres。
我想带着三个问题离开这个房间:
第一,哪些目录指标真正有用?页面访问量、下载量、包可用性、构建失败、最近发布日期、对象冲突。哪些应该被公开展示,哪些只是噪音?
第二,扩展构建覆盖率能否帮助补丁评审?它是否能作为 API、ABI 和行为变化的早期预警信号?
第三,其中一些元数据是否应该更靠近 PostgreSQL 社区基础设施?放在 postgresql.org 下,和 PGDG 放在一起,还是放在别的地方?
扩展是共同基础设施。交付是可扩展性的一部分。如果我们改善交付,PostgreSQL 的超能力就能触达更多人。
32. 致谢
谢谢大家。
如果有任何问题,欢迎联系我。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
6 - 504 个扩展,PG 生态的天花板在哪?
一个 Issue ,引发扩展马拉松;32 个新扩展告诉你,PostgreSQL 正在变成什么;504 个扩展,PostgreSQL 生态的天花板在哪?
从一个化学扩展说起
两天前,一位用户在 GitHub 上给我提了个 Issue:他在用 RDKit —— 化学信息学领域的事实标准库,能在 PostgreSQL 里做分子结构存储、子结构检索和相似性计算。 但他发现 PGDG 官方打包的版本缺了 InChI 功能,他自己折腾了半天,加上编译参数后总算跑通了,但还是希望 Pigsty 能原生支持。
但 RDKit 确实是个硬骨头。大约两年前我就试过一次,想把它收进 Pigsty 的扩展仓库,从 Debian 移植到 EL。 结果依赖太多了:Boost、Eigen、RapidJSON、Cairo,外加 InChI、Avalon 等可选模块, 每个都有自己的编译开关和操作系统默认库版本兼容问题。折腾了一会没跑通,就先搁置了。
但这次不一样。有 Coding Agent 了。
用 Codex / Claude Code 处理这类"构建系统考古"任务简直是降维打击 —— 以前需要反复试错的东西,现在基本一两轮对话然后等着就行了。 这次发布,把 PGDG 打包到 InChI 支持的问题也一并解决了,本质上就是编译时多开一个标志位再带上 InChI 源码。一把过,用户也很满意。

说实话,看到这种反馈挺开心的。做开源最爽的就是这个时候。
趁热打铁
既然手热了,我就顺便把积压已久的几个"历史疑难杂症"也一起清了。
plv8:V8 引擎的 PostgreSQL 绑定,之前在 EL10 上死活编译不过,这次打了好几个补丁终于搞定了稳定构建。
duckdb_fdw:允许从 PG 内部读写外部 DuckDB 文件,但之前会和 DuckDB 官方的 pg_duckdb 扩展争抢共享库,我只能忍痛临时隐藏。这次把 duckdb_fdw 挂成了 pg_duckdb 的子扩展,共享同一份 libduckdb,冲突问题优雅解决,俩扩展又能并存了。
然后我就想:既然工具链都热好了,不如把 PostgreSQL 生态里剩下那些值得收录但一直没啃的扩展也一并搞进来吧。 于是就有了这次的大更新 —— 新增 32 个扩展,更新 22 个,Pigsty 扩展仓库总数正式突破 500,达到 504 个。
| 分类 | All | PGDG | PIGSTY | CONTRIB | MISS | PG18 | PG17 | PG16 | PG15 | PG14 |
|---|---|---|---|---|---|---|---|---|---|---|
| 全部 | 504 | 155 | 332 | 71 | 0 | 481 | 488 | 479 | 473 | 457 |
| EL | 499 | 150 | 332 | 71 | 5 | 472 | 482 | 474 | 468 | 452 |
| Debian | 489 | 107 | 311 | 71 | 15 | 466 | 474 | 464 | 458 | 442 |
这五百个扩展中,一部分是 PG 自带的扩展(70个),PGDG 官方打包的扩展(150 个),剩下的 330 个都是老冯自己收录,打包,维护构建的第三方扩展。 基本上,Pigsty 在这个赛道上已经做到了前无古人,后无来者了。
这是啥概念?一般 RDS PG 上也就是几十个扩展。比如最近火爆的 Supabase 上,去掉 PG 自带的的 35 个 Contrib 扩展,实际上也就提供了 30 个不到的第三方 PG 扩展。
新扩展
这批新增扩展的画风相当硬核。按大类可以分四组:
数据域扩展:把化学分子、RDF 三元组、BSON、Protobuf、循环日程这些"复杂对象"变成数据库一等公民;
查询能力扩展:稀疏线代与图算法、Datalog 图查询、全文检索、混合排序融合、递归 SQL 模板引擎;
生产工程扩展: 深度可观测性、查询遥测导出、CDC 到 MQTT、COPY 命令拦截、DDL 逻辑复制补全、轻量分布式锁、软告警式数据质量管理;
开发者体验扩展: 会话变量、伪自治事务日志、自然语言时间解析
这些扩展共同指向一个趋势:PostgreSQL 的扩展层正在把数据库推向应用与数据平台的中间地带。很多原本需要独立服务才能解决的问题,现在可以在一条 SQL 事务边界内搞定。
这就是 PostgreSQL 极致可扩展性的魅力所在。
新扩展大观园
这次新加入了 32 个新扩展,下面的部分是请 Claude/Codex/Gemini 三剑客进行研究汇总摘要,用于帮助读者快速了解每个扩展的核心功能、技术实现和适用场景。
1. rdkit: 把化学信息学搬进 PostgreSQL
RDKit 是开源化学信息学领域的事实标准库,由 Greg Landrum 发起(最初在 Novartis,现属 T5 Informatics),其 PostgreSQL cartridge 模块将分子结构存储、子结构检索和相似性计算直接带入关系数据库。对于制药公司和化学研究机构而言,这意味着可以用标准 SQL 查询数百万化合物,无需借助外部工具链。
RDKit cartridge 引入了两组核心数据类型:mol(分子)和 qmol(查询分子,即 SMARTS 模式),以及 bfp/sfp(位指纹/稀疏指纹)。操作符方面,@> 用于子结构匹配,% 用于 Tanimoto 相似性判断,<%> 作为距离运算符。所有这些操作都可以通过 GiST 索引 加速——索引内部基于指纹筛选进行快速预过滤,再做精确匹配。关键函数包括 mol_from_smiles()、morganbv_fp()(Morgan 指纹)、tanimoto_sml() 等,配合 rdkit.tanimoto_threshold 等 GUC 参数可以调节检索灵敏度。
以 ChEMBL 数据库(187 万化合物)为例:
应用场景集中在药物研发的几个关键环节:先导化合物骨架搜索(在百万级化合物库中做子结构匹配)、SAR 分析(通过相似性检索寻找活性类似物)、化合物注册系统(利用结构指纹做重复性检查)、以及 商业化合物目录检索(如 eMolecules 的 600 万+化合物数据集)。
工程落地时需要注意:cartridge 的重点不在"能不能算",而在"能不能被索引、能不能被 planner 正确利用"。索引策略与查询模板需要提前固定下来,否则很容易写出正确但慢的结构过滤。在 187 万化合物上子结构检索耗时在 88ms 至 1900ms 之间,经过优化可以处理 600 万+化合物 规模的数据集。BSD 许可证,Docker 镜像(如 mcs07/postgres-rdkit)和 conda 安装均已就绪。
2. provsql: 半环溯源让查询结果"可追溯"
ProvSQL 由巴黎高等师范学校教授 Pierre Senellart 和 INRIA Valda 团队开发,发表于 VLDB 2018。它为 PostgreSQL 添加 (m-)半环溯源(semiring provenance) 和不确定性管理——能自动追踪每个查询结果是由哪些基础元组"推导"出来的,并支持在不同代数结构(布尔、安全等级、计数、概率)下对溯源信息进行求值。
核心机制是通过 PostgreSQL hook 拦截查询执行,为每个表自动添加一个隐藏的 provsql 列,存储指向溯源电路(provenance circuit)的 UUID。支持的 SQL 子集相当广泛:SELECT-FROM-WHERE、JOIN、GROUP BY、DISTINCT、UNION/EXCEPT、聚合、HAVING,甚至在 PG 14+ 上支持 INSERT/DELETE/UPDATE 的溯源追踪。核心函数包括 add_provenance() 启用追踪、provenance_evaluate() 对溯源进行求值、formula() 输出布尔公式、probability_evaluate() 计算概率。概率求值支持多种算法:从朴素求值到 Monte-Carlo 采样,再到 d-DNNF 编译(借助 d4、c2d 等外部求解器)。
ProvSQL 适合四类场景:安全分级传播——查询结果自动继承源数据中最高的安全等级;概率数据库——当基础数据带有可信度评分时,计算查询结果的正确概率;数据血缘审计——精确追踪每个结果行来源于哪些源元组,并支持 PROV-XML 标准导出;可信度评估——例如在刑事调查场景中,通过溯源加权评估目击者陈述的可靠性。
ProvSQL 的价值往往体现在"可组合性":溯源结果不是字符串日志,而是可以继续被函数处理的对象。建议用于关键链路(核心报表/模型特征/合规计算),而非全库无差别开启。C/C++ 实现(依赖 Boost 库),溯源电路存储在共享内存中。支持 PG 10–18,MIT 许可证。
3. one_sparse: 在 SQL 里跑十亿边级图算法
OneSparse 将高性能稀疏线性代数带入 PostgreSQL,封装了 SuiteSparse:GraphBLAS 库。开发者 Michel Pelletier 是 GraphBLAS C API 委员会成员,顾问团队包括 SuiteSparse 作者 Timothy A. Davis 教授(SIAM/ACM/IEEE Fellow)。核心理念是 将图表示为稀疏矩阵,用矩阵乘法实现 BFS、PageRank、三角中心性等图算法——而这一切都在 SQL 中完成。
扩展引入了 matrix(稀疏矩阵)、vector(稀疏向量)、scalar、semiring、monoid 等数据类型,以及 @(矩阵乘法/plus_times 半环)等操作符。图算法方面内置了 BFS(层级和父节点两种模式)、PageRank、三角中心性、度中心性、单源最短路径等,均来自 LAGraph 库。技术上,它将 GraphBLAS 的不透明句柄封装在 PostgreSQL 的 Expanded Object Header 结构中,小图(<1GB)使用 TOAST 存储,大图支持 Large Object 或文件系统。内置 JIT 编译器支持 NVIDIA CUDA GPU 加速。
在 GAP benchmark 上,对 43 亿边 的图执行 BFS 时达到了 每秒 70 亿+边 的吞吐量(48 核 AMD EPYC 服务器)。应用场景包括金融反欺诈(交易网络环检测)、社交网络分析、Graph RAG 等。不过,这类扩展是否"真好用",取决于数据装载/序列化格式是否与现有管道匹配,以及算子能否与 SQL Planner/并行执行相处融洽——建议先用小规模样例把端到端链路跑通。
OneSparse 要求 PG 18 Beta 或更新版本,当前处于 Alpha 阶段。Apache 2.0 许可证。
4. pg_datasentinel: 容器时代的 PostgreSQL 深度可观测性
pg_datasentinel 由 Datasentinel 公司的 Christophe Reveillère 开发,于 2026 年 4 月 10 日发布 1.0 版本。它为 PostgreSQL 添加了四大可观测性能力,填补了原生监控视图在容器化环境和运维预警方面的空白。
第一,扩展活动监控:在 pg_stat_activity 基础上增加每个后端进程的内存使用量、实时临时文件字节数,以及在 PG 18+ 上显示当前执行计划 ID。第二,容器资源可见性:报告 CPU 配额、内存限制、当前内存使用和 CPU 压力,适用于 Docker、Kubernetes、OpenShift 或任何 cgroup 管理的环境。第三,事务回卷风险预估:追踪 XID 和 MXID 消耗速率,提供到 aggressive-vacuum 和回卷限制的 实时 ETA。第四,日志捕获视图:将 vacuum、analyze、临时文件、checkpoint 事件记录到共享内存环形缓冲区,解析为结构化计数和计时信息,支持实时 SQL 查询。
对于在 Kubernetes 上运行 PostgreSQL 的团队,pg_datasentinel 提供了无需外部监控代理即可获得的容器级资源可见性。XID 回卷预警 功能对运维尤为关键——众所周知,XID 回卷会导致数据库强制关闭,而 pg_datasentinel 通过追踪消耗速率提供预测性告警,将"救火"变为"防火"。3-Clause BSD 许可证,要求 PG 15+。
5. datasketches: Apache 出品的亿级近似分析利器
Apache DataSketches 是 Apache 基金会项目(源自 Yahoo/Verizon Media),其 PostgreSQL 扩展将多种 近似分析数据结构(Sketch) 引入 SQL 世界。核心问题很明确:在海量数据上做精确的 COUNT(DISTINCT)、分位数计算和频繁项统计太慢或太耗内存。
扩展提供七种 Sketch 类型:cpc_sketch(Compressed Probabilistic Counting)、hll_sketch(HyperLogLog)、theta_sketch(支持集合交并差运算的去重计数)、aod_sketch(Tuple sketch)、kll_float_sketch/kll_double_sketch(分位数估算)、req_float_sketch(尾部高精度分位数)、frequent_strings_sketch(频繁项)。每种 Sketch 都提供 *_sketch_build()、*_sketch_union()、*_sketch_get_estimate() 等标准接口。
关键点不是"有个函数返回估计值",而是 Sketch 作为 可序列化对象可以被聚合合并,因此特别适合数据立方体式的近似指标:按维度切片预聚合 Sketch,查询时按任意维度组合做 union 即可得到去重数。Sketch 在内存中是 亚线性 的,且可跨语言(Java、C++、Python、Rust、Go)做二进制兼容序列化。
典型应用:实时 UV 统计——不存储用户 ID 即可跨时间窗口合并去重;分布分析——在数十亿事件上计算 p50/p95/p99 延迟而无需排序;受众重叠分析——用 Theta Sketch 的交集运算计算"看过广告 A 且访问过网站 B"的用户数。在 1 亿行数据上,CPC Sketch 的去重计数约 20 秒完成(精确 COUNT(DISTINCT) 约 2 分钟),相对误差在个位数百分比范围内。
6. pghydro: 巴西国家水务局的排水网络分析引擎
PgHydro 由巴西国家水务卫生局(ANA)的 GIS 专家 Alexandre de Amorim Teixeira 开发,构建在 PostGIS 之上,被 ANA 作为水资源管理的官方工具在全国范围内使用,也在 FOSS4G 2022 上做过展示。
核心能力围绕水文网络的完整工作流展开:从原始 GIS 数据的导入和一致性校验,到流向计算、Otto Pfafstetter 流域编码(一种国际通用的分层流域分类系统)、上下游分析、汇水面积计算、Strahler 河流分级等。架构上采用模块化设计,包含五个子扩展:pghydro(核心)、pgh_raster(DEM 栅格分析)、pgh_hgm(水文地貌特征)、pgh_consistency(拓扑一致性校验)和 pgh_output(数据导出)。
适用于国家级水文数据库管理、流域规划与编码、上下游污染影响分析(如确定某污染源上游的所有河段)、以及排水网络拓扑一致性验证。它更像一套专业领域的数据库内 ETL/分析流水线——数据在 PostGIS 中管理,分析过程可在 SQL 里自动化,当原始地形/河网数据更新时,按函数流水线重算比手动脚本更可靠。配合 QGIS 的 PgHydroTools 插件可实现可视化操作。完全用 PL/pgSQL 编写,GPLv2 许可证。
7. pg_stat_ch: ClickHouse 官方出品的 PostgreSQL 查询遥测
pg_stat_ch 由 ClickHouse 公司开发并开源(2025 年 2 月,“Postgres Week at ClickHouse"活动),作者是 Kaushik Iska。与 pg_stat_statements 在 PostgreSQL 内部做聚合统计不同,pg_stat_ch 将 每条查询的原始执行事件(包含 45 个字段、固定 4.6KB)实时流式导出到 ClickHouse,让所有聚合分析(p50/p95/p99、Top 查询、错误分析)在 ClickHouse 的分析引擎中完成。
数据管道架构为:PostgreSQL Hooks(前台)→ 共享内存环形缓冲区 → 后台 Worker → ClickHouse。45 个遥测字段覆盖查询计时、行数、缓冲区使用、WAL 使用、CPU 时间、JIT 指标(PG15+)、并行 Worker 统计(PG18+)、客户端上下文(应用名、IP)、错误捕获(SQLSTATE 码)等。扩展使用 ClickHouse 原生二进制协议加 LZ4 压缩,静态链接 clickhouse-cpp 库。为避免对 PostgreSQL 造成背压,队列溢出时丢弃事件(计数器记录丢弃数)而非减慢数据库——与 StatsD 的设计哲学一致。
ClickHouse 侧预置了四个物化视图:events_recent_1h(滚动 1 小时副本)、query_stats_5m(5 分钟桶 + TDigest 分位数)、db_app_user_1m(按数据库/应用/用户的负载归因)、errors_recent(7 天滚动错误窗口)。
性能令人印象深刻:p99 开销约 5μs/条,在 pgbench 32 客户端 36.6K TPS 下,30 秒内捕获 770 万事件且零丢弃,对 TPS 影响 <1%(36,658 vs 36,913 基线)。三层锁争用最小化策略:原子溢出检查 → 非阻塞 LWLock 尝试 → 每后端本地缓冲区(每事务刷新,减少约 5 倍锁获取次数)。把 PostgreSQL 做成"事务系统”,ClickHouse 做成"遥测仓库",职责分离,比从日志文件逆向解析稳定得多。支持 PG 16–18,Apache 2.0 许可证。
8. pg_rrf: 一个函数搞定混合检索的排序融合
pg_rrf 由日本开发者 yuiseki 开发(2026 年 1 月发布),用 Rust(pgrx)实现。它将 Reciprocal Rank Fusion(RRF) 封装为原生 PostgreSQL 函数,解决混合检索场景中"分数不可比"的工程痛点:不同检索器输出尺度不同,直接加权不好调,而 RRF 只依赖 rank。公式为 score(d) = Σ 1/(k + rank_i(d)),k 默认 60(Cormack et al., SIGIR 2009)。
扩展提供四个函数:rrf(rank_a, rank_b, k) 计算两路融合分数、rrf3() 三路融合、rrfn(ranks[], k) N 路融合、以及最实用的 rrf_fuse(ids_a bigint[], ids_b bigint[], k)——接收两个排序后的 ID 数组,返回融合后的 (id, score) 表。NULL 安全:只在一路出现的 ID 仅使用该路的排名计算得分。
这将原本需要 FULL OUTER JOIN + COALESCE 链 + 手动评分公式的 20+ 行 CTE 压缩为一个函数调用。应用场景覆盖 RAG 混合检索(语义搜索 + 全文搜索融合)、电商产品搜索、多信号文档排序等。把融合逻辑移到数据库侧,尤其当结果要继续 JOIN 业务表时,减少了应用层拼接与排序的开销。当前 v0.0.3,MIT 许可证。
9. pg_kazsearch: 哈萨克语全文检索的"从无到有"
pg_kazsearch 是首个 PostgreSQL 哈萨克语全文检索扩展。哈萨克语是高度黏着语(agglutinative),一个词如 мектептерімізде 承载了复数、领属、位格等多层后缀,必须全部剥离才能到达词根 мектеп。现有的 PostgreSQL 或 Elasticsearch 分析器都无法处理这一点。
扩展用 Rust(pgrx)实现,提供 kazakh_cfg 文本搜索配置和 pg_kazsearch_dict 词典。词干提取算法采用 BFS 后缀剥离,配合元音和谐验证和基于 Apertium-kaz 的 21,863 个词性标注词根词典 防止过度词干化。运行时可通过 ALTER TEXT SEARCH DICTIONARY 调整权重参数。
在 2,999 篇文章上的基准测试显示:查询延迟 0.5ms(比 pg_trgm 快 2.8 倍),nDCG@10 提升 25%,Recall@10 提升 23%。适用于哈萨克语新闻/政府文档检索、电商搜索等场景——在多语种系统里把"低资源语言"检索能力补齐,避免回退到粗糙的 trigram 模糊匹配。
10. pg_liquid: Datalog 风格的图查询
pg_liquid 由 Michael Golfi 开发,把 Liquid/Datalog 风格的声明式图查询带进 PostgreSQL。你可以用 liquid.query(...) 在一次调用里声明事实、定义规则并执行终止查询,不必单独搭图数据库。规则是 query-local(只在一次 liquid.query 中有效),支持事实断言、递归传递闭包、复合查询(compounds)和行规范化器。
它还支持把本体谓词定义(如 DefPred)与 compound(如 OntologyClaim@(...))结合,用 compound 携带溯源/置信信息,靠规则做 subclass closure 等推理。适合知识图谱查询、层级数据遍历(组织架构、分类树)、基于规则的业务逻辑系统等场景——当你不想引入独立图引擎时,用扩展把最关键的递归查询补上。完全用 PL/pgSQL 实现,无外部依赖,项目处于早期阶段。
11. logical_ddl: 让逻辑复制也能同步 DDL
PostgreSQL 的逻辑复制只处理 DML(INSERT/UPDATE/DELETE),不处理 DDL(ALTER TABLE 等),这是运维中的一大痛点——表结构不同步会直接中断复制。logical_ddl 由 Samed Yildirim 开发,通过 事件触发器 拦截 DDL 命令,将其反解析并保存到可被逻辑复制传播的表中,订阅端接收后生成等效 SQL 并执行。
支持的 DDL 操作包括:ALTER TABLE RENAME TO/RENAME COLUMN/ADD COLUMN/ALTER COLUMN TYPE/DROP COLUMN。数据类型兼容性方面:内建类型、数组、复合/域/枚举类型可用,但这些类型的"定义复制"(如 CREATE TYPE)不在覆盖范围内。可通过 logical_ddl.publish_tablelist 按表和命令类型精细控制捕获范围。
适用于逻辑复制环境的自动化 DDL 同步、零停机迁移、多数据中心 PostgreSQL 架构等。把"DDL 同步"从流程管理变成可审计的数据流,降低复制事故概率。MIT 许可证,PGXN 可用。约束、索引、默认值等尚未实现。
12. rdf_fdw: 用 SQL 查询语义网
rdf_fdw 由 Jim Jones 开发,是一个通过 SPARQL 端点访问 RDF 三元组存储的 Foreign Data Wrapper,架起关系型 SQL 世界与语义网/关联数据世界之间的桥梁。它引入 rdfnode 数据类型处理 RDF 术语(IRI、语言标签、数据类型),支持 WHERE/LIMIT/ORDER BY/DISTINCT 等条件的 SQL-to-SPARQL 下推,以及通过 SPARQL UPDATE 端点执行 INSERT/UPDATE/DELETE。
rdf_fdw_clone_table() 存储过程支持将外部表数据分批克隆到本地表。需要注意的是,实现层面会把拉取到的数据加载到内存再转换,面对大体量数据要谨慎评估内存与下推效果。适合关联数据集成(DBpedia、Wikidata)、用 SQL/BI 工具链直接消费 SPARQL 端点等场景。MIT 许可证,支持 PG 9.5–18。
13. pgbson: 比 JSONB 更精确的二进制文档类型
pgbson(postgresbson)由 buzzm 开发,为 PostgreSQL 引入原生 BSON(Binary JSON)数据类型。BSON 相比 JSON 提供了一等公民的 datetime、decimal128、int32/int64、binary 等类型,解决了 JSON 在分布式系统数据交换中的精度丢失和类型模糊问题,保证 二进制完美往返(BSON in = BSON out)。
核心 API 是两类访问方式:一类是高性能的 dotpath 函数——bson_get_string(bson, 'd.recordId')、bson_get_datetime()、bson_get_decimal128() 等,直接在底层结构上行走,只在终点分配内存;另一类是类似 JSON 的 -> / ->> 链式操作符,但每一步都要构造中间子结构,深层路径会放大成本。两者配合 B-Tree 和 HASH 索引,函数索引可实现 10,000 倍 的查询加速(相对于顺序扫描)。输入端支持 EJSON 格式。
典型场景包括跨语言事件/文档管道(Java → Kafka → Python → PostgreSQL)的精确类型保持、金融数据(decimal128 精确到分)、数字签名(BSON 的确定性二进制格式支持可靠哈希)等。MIT 许可证,支持 PG 14–18。
14. pg_when: 用自然语言描述时间
pg_when 由 frectonz 开发,把自然语言时间表达解析成 PostgreSQL 的 timestamptz 或 epoch。核心函数 when_is(text) 返回标准 timestamp,语法由三部分组成:日期 + at + 时间 + in + 时区。未指定时区时默认 UTC。
另有 seconds_at()、millis_at()、micros_at()、nanos_at() 返回 UNIX 时间戳的不同精度。这不是调度器,而是解析器。适用于面向运营/客服的"人类时间输入"落库、数据修复/回填脚本中用自然语言代替拼日期函数、以及统一时区处理等场景。MIT 许可证。
15. pgmqtt: 数据库变更直推 MQTT
pgmqtt 由 RayElg 开发(Rust 实现),把 PostgreSQL 的变更(INSERT/UPDATE/DELETE)通过 CDC 直接变成 MQTT 消息推给订阅者,同时也支持 MQTT 入站消息按映射写回表。它不是通用 MQTT 客户端,而是把"变更流"与"消息 broker"嵌到数据库侧,用 SQL 配置 topic 映射与 payload 模板。
IoT 场景尤其合适——无需外部中间件即可将数据库状态变化推送到边缘设备,或将传感器数据通过 MQTT 协议直接写入表。也适用于事件驱动架构中的轻量消息分发,减少应用层的 glue code。Elastic License 2.0。
16. pg_query_rewrite: 透明地偷梁换柱
pg_query_rewrite 由 Pierre Forstmann 开发,利用 ProcessUtility hook 实现 SQL 语句的运行时透明替换。规则基于 精确字符串匹配(大小写和空格敏感)存储在共享内存中。
这是一个"很锋利"的工具:不支持带参数的语句、最大长度约 32KB、匹配对大小写/空格/分号敏感、规则不持久化(重启丢失,需借助启动 SQL 机制恢复)。适用于数据库迁移期间对历史系统发出的固定 SQL 做透明重定向、危险查询临时拦截、查询 A/B 测试等。默认最多 10 条规则,支持 PG 9.5–18。
17. pgclone: 一键克隆数据库对象
pgclone 由 valehdba 开发(PGXN 上发布 2.0.0 版),定位非常直给:不用 pg_dump/pg_restore、不用 shell 脚本,直接从 SQL 调用函数把表、schema、数据库、函数(甚至角色与权限)从源实例克隆到目标环境。
它使用 COPY 协议进行快速数据传输,支持异步操作与进度跟踪,支持选择性克隆(列/行过滤),DDL 也在覆盖范围内(索引、约束、触发器、视图、物化视图、序列等),还提供数据脱敏与敏感列自动发现能力。
适用于开发/测试环境快速搭建(含 DDL、索引)、生产到预发的"带脱敏克隆"、多库迁移与验证等。相比 pg_dump/pg_restore,它完全在数据库内部完成,简化了 DevOps 流程。
18. pgproto: 原生 Protobuf 支持
pgproto 由 Apaezmx 开发,为 PostgreSQL 提供原生 Protocol Buffers(proto3)存储、查询、修改和索引支持。核心机制是"运行时 Schema 注册 + 二进制遍历":把 FileDescriptorSet 注册到 pb_schemas 后,protobuf 类型的列就能通过路径数组提取嵌套字段。引入 -> 字段导航、#> 嵌套路径访问、|| 消息合并等操作符,以及 pb_set()/pb_insert()/pb_delete()/pb_to_json() 等函数。
在 10 万行基准测试中,pgproto 存储仅 16 MB(JSONB 46 MB,原生关系 25 MB),全文档检索 5.9ms(关系模型 33.1ms 需多表 JOIN)。想保留 Protobuf 生态(RPC/消息)又希望数据库侧可索引可过滤时,这是一个有吸引力的选择。适合 IoT 数据存储、微服务事件仓库、gRPC 数据层等。PostgreSQL License。
19. pg_fsql: JSONB 驱动的递归 SQL 模板引擎
pg_fsql 由 yurc 开发,把"SQL 模板渲染 + 安全参数化执行 + 模板树递归组合"做成扩展。模板按 dot-path 组成树,子模板产出片段或 JSON,再注入父模板。支持占位符语法({d[key]} 及不同转义 !r/!j/!i)、SPI plan cache(按模板可选缓存)、多种命令类型(exec/ref/if/exec_tpl/map/NULL),以及 fsql.run 执行、fsql.render dry-run、fsql.tree、fsql.explain 等公共 API。不需要 superuser。
这不是函数式 SQL,而是层次化模板引擎:目标是让你用 JSON 请求体驱动 SQL 生成,减少应用层代码分支。适用于动态报表生成、ETL 管道编排、多租户查询生成、以及把差异化 SQL 固化在模板表中配合权限管理等场景。
20. pg_dispatch: 基于 pg_cron 的异步 SQL 分发
pg_dispatch 由 Snehil Shah 开发,是一个异步任务分发器,定位为 TLE 兼容的 pg_later 替代品,底层依赖 pg_cron。核心函数 pgdispatch.fire(command) 立即异步执行 SQL,pgdispatch.snooze(command, delay) 延迟执行。设计目标是解锁主事务——当 AFTER INSERT 触发器需要执行重操作时,将其卸载为后台任务。
TLE 兼容(纯 PL/pgSQL),可在 Supabase 和 AWS RDS 等沙盒环境使用。依赖 pg_cron >= 1.5。适合触发器/函数内的异步副作用(通知、异步汇总、写审计表等),避免长事务占用连接。
21. block_copy_command: 安全加固:阻止 COPY 命令
block_copy_command 由 rustwizard 开发(Rust/pgrx),通过 ProcessUtility hook 集群范围内拦截 COPY 命令。在安全敏感环境(PCI-DSS、HIPAA 合规)中防止通过 COPY TO 进行数据外泄或通过 COPY FROM 进行未授权数据导入。
它提供基于角色的 blocklist、方向控制(block_to/block_from),以及对 COPY ... TO PROGRAM 的强制阻断(默认对所有用户拦截)。blocked_roles 甚至能阻止 superuser。支持审计日志记录。
适用于托管/共享环境(防止租户用 COPY 导数据)、企业合规(统一拦截与审计)、ETL 权限收敛(通过 GUC/角色配置精确允许导入、阻断导出)。作者还维护了更全面的命令防火墙扩展 pg_command_fw。
22. pg_isok: 数据质量的"软告警"系统
pg_isok(Isok)由 Karl O. Pinc 开发,已在生产环境使用超过十年。它不是传统约束/触发器,而是"软触发器"式的数据完整性管理:你写一条能找出可疑数据模式的 SQL,Isok 负责记录/分类/延后这些发现,并报告"新增问题或已接受数据的变化",避免你反复审阅同一批历史问题。
与硬约束(拒绝数据)不同,它允许存在可疑数据但持续追踪和管理——通过 isok_queries 和 isok_results 等表组织工作流,run_isok_queries 函数执行检查,逐行接受或延迟告警。适合"脏数据导入后逐步清理"“业务规则模糊、需要人工裁决"的场景。能写 SQL 就能上线一套"告警 + 去重 + 延期"机制。
23. external_file: PostgreSQL 版的 Oracle BFILE
external_file 由 Gilles Darold(HexaCluster Corp)维护,提供与 Oracle BFILE 等效的功能:通过目录别名 + 文件名的 EFILE 类型引用服务器端外部文件,支持读取(readEfile())、写入(writeEfile())和复制(copyEfile())。通过 lo_* 相关机制执行读写,并用目录别名表与权限表控制可访问范围。
为 Ora2Pg 迁移场景量身定制,也适合"文件在库外、元数据在库内"的遗留系统,以及数据库侧管理外部大对象的批处理导入导出。
24. pg_byteamagic: 检测 bytea 的文件类型
byteamagic 由 Nico Mandery 开发,封装 libmagic(Unix file 命令背后的库),提供两个函数:byteamagic_mime(bytea) 返回 MIME 类型,byteamagic_text(bytea) 返回人类可读的文件描述。
当你不得不在表里存 bytea/BLOB 时,可以在 SQL 里识别这段二进制到底是 PDF、PNG 还是其它格式。适合附件/上传内容治理(识别真实类型、防止伪装)、Content-Type 自动识别、历史 BLOB 数据清理等。
25. pg_text_semver: 语义版本号的原生支持
pg_text_semver 由 Rowan Rodrik van der Molen 开发,基于 text DOMAIN 实现完全符合 Semantic Versioning 2.0.0 规范的版本类型。与 C 实现的 semver 扩展不同,它对版本号各部分 没有 32 位整数的大小限制。
纯 SQL 实现,支持 min/max 聚合和 PGXN Version Range 检查。适用于扩展/包版本管理、依赖约束校验、版本分布统计等。
26. parray_gin: text[] 的子串匹配索引
parray_gin 由 Eugene Seliverstov 开发,为 text[] 数组列提供基于 GIN 索引的 部分匹配 操作符。标准 PostgreSQL 的 GIN 数组操作符只支持精确元素匹配,parray_gin 新增的 @@> 操作符支持子串包含判断,底层基于 trigram 分解(复用 pg_trgm 的实现),并通过 recheck 处理 false positive。
适合标签系统自动补全、模糊标签搜索等场景——让数组模糊匹配进入索引路径,替代应用层扫描。支持 PG 9.1–18。
27. pg_slug_gen: 加密安全的时间戳短标识
pg_slug_gen 由 Fernando Olle 开发,生成基于时间戳的加密安全唯一短标识。使用 pg_strong_random() 选择字符,slug 长度决定时间戳精度:10 字符(秒)、13(毫秒)、16(微秒,默认)、19(纳秒)。
注意这不是 URL slug 生成器(从标题转写),而是面向"安全短 ID"的方案。适合邀请码/短链接/公开资源 ID(避免自增 ID 暴露业务规模)、分布式写入(用时间戳维度做可控的无碰撞窗口)等。比 base62(序列) 更难预测。
28. pglock: PostgreSQL 内的轻量级分布式锁
pglock 由 fraruiz 开发,在 PostgreSQL 内部实现轻量级分布式锁服务。它基于一张锁表和一组函数(pglock.lock/pglock.unlock/pglock.ttl/pglock.set_serializable)实现,支持 TTL 过期机制(默认 5 分钟),可选配合 pg_cron 定时执行 pglock.ttl() 清理过期锁。建议使用 SERIALIZABLE 隔离级别以保证并发语义正确。
无需外部依赖(Redis、ZooKeeper 等),适用于多实例应用抢占任务/资源(定时任务、幂等消费者)、Leader 选举、防止重复任务执行等场景。锁行为与业务写入可在同一数据库生态里治理。纯 SQL 实现。
29. pg_regresql: 让规划器信任 pg_class 统计信息
pg_regresql 是 boringSQL 的 Radim Marek 做的一个小扩展,专门解决计划回归测试里的一个老问题:即便你向 pg_class 注入了生产环境统计信息,PostgreSQL Planner 仍会去读磁盘上的真实文件大小,再按比例缩放行数估计。这样一来,选择率虽然还是对的,但 EXPLAIN 的绝对 cost 会被测试库的体量拉小,无法稳定复现生产环境的估算结果。
这个扩展通过 get_relation_info_hook 直接改写 Planner 读取到的关系与索引统计,把 relpages、reltuples、relallvisible 等值替换成 pg_class 中的目录统计。这样做的效果很直接:在 CI 中对比 EXPLAIN 成本、在本地复现生产计划、或者维护可移植的计划基线时,估算值终于能和注入的统计信息保持一致。
它只影响规划阶段的成本估计,不会改变真实执行过程,也不会篡改 EXPLAIN ANALYZE 的实际行数。因此这玩意适合测试环境和 CI,不适合生产库。BSD 2-Clause 许可证。
30. pgcalendar: 循环日程的无限投影
pgcalendar 由 h4kbas 开发,提供完整的循环事件日历系统:事件(events)是逻辑实体,日程(schedules)定义循环模式(每日/每周/每月/每年),投影(projections)生成实际发生时间,例外(exceptions)修改单个实例(取消、改期)。
“无限投影"“多段 schedule 配置切换"“例外处理"这类能力在排班、会议、计费周期等场景很常见,但靠应用层自己拼往往细节爆炸。把日程逻辑放数据库后,权限、审计与一致性约束更容易统一。
31. pg_variables: 比临时表更快的会话变量
pg_variables 由 Postgres Professional 开发,提供会话级变量支持,涵盖标量、数组和记录(集合)类型。变量按命名包(package)组织,“是否事务性"可配置:默认变量不随 BEGIN/ROLLBACK 回滚,但 is_transactional = true 时遵守 ROLLBACK/SAVEPOINT。
作为临时表的高性能替代,避免了目录膨胀(catalog bloat)。适合复杂存储过程/批处理中保存中间状态、连接级信息缓存,也作为其它扩展的基础设施(如 pgelog 用它缓存 dblink 连接)。
32. pgelog: 回滚也丢不掉的日志
pgelog 由 anfiau 开发,通过 dblink 实现 伪自治事务,使日志记录在调用事务回滚时依然存活。这解决了 PL/pgSQL EXCEPTION 块中的日志在 ROLLBACK 后丢失的经典问题。dblink 连接通过 pg_variables 做会话级缓存优化。
关键流程审计时,你不想因为业务事务回滚就丢失诊断线索。批处理/迁移脚本中,阶段性日志比单纯 RAISE NOTICE 更可查询。依赖 dblink 和 pg_variables 扩展,每个会话可能额外打开一个连接,需评估 max_connections。
总结
这 33 个扩展背后有几条清晰的趋势线。
第一,PostgreSQL 正在通过扩展把"专业对象"内建化。 BSON、Protobuf、RDF、循环日程、化学分子、图/本体关系——这些扩展把数据库从"结构化表"推向"可查询的复杂对象存储”。权限、审计、备份、事务语义都沿用数据库基础设施,减少了数据搬运和外部服务依赖。
第二,查询能力在向"组合式 API"演化。 RRF 融合、SQL 模板树、查询重写、稀疏计算、近似摘要结构——这些扩展的共同目标是让复杂逻辑以更少、更稳定的 SQL 片段表达,同时保持可审计、可复跑和可优化。
第三,生产工程与平台化在加速。 从 pg_stat_ch 的实时遥测外送、pg_datasentinel 的容器资源可见性,到 block_copy_command 的安全钩子、pg_isok 的软告警治理——扩展层正在承接越来越多"原本要靠外部系统"的能力。
第四,垂直领域渗透持续加深。 从化学信息学(rdkit)、水文分析(pghydro)到哈萨克语 NLP(pg_kazsearch),PostgreSQL 正在成为越来越多专业领域的计算底座。
PostgreSQL 的扩展生态就是这样:既有大教堂(Apache 基金会项目),也有集市(个人开发者的周末项目),共同构建着世界上最先进的开源数据库。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
7 - PG 扩展百科全书:中英双语,开箱即用
扩展是 PostgreSQL 的灵魂。没有扩展的 PostgreSQL,只是一个普通的关系型数据库;有了扩展的 PostgreSQL,才是那个能吞噬整个数据库世界的超级平台。
但长期以来,PG 扩展生态一直面临一个尴尬的问题:找不到、看不懂、装不上。你想用一个扩展,得先去 GitHub 翻 README,再去 PGXN 碰运气看有没有包,然后对着不同操作系统的包管理器折腾半天。运气好装上了,运气不好,编译失败、依赖缺失、版本不兼容,一下午就没了。
所以我做了一件事:把 PostgreSQL 生态里收录的 464 个扩展,每一个都做成一张完整的“身份证”,整理成一个中英双语的扩展百科全书。当然,它不只是百科全书,还是一套真正可交付的二进制仓库。我们提供 14 个 Linux 平台、最近 5 个 PG 大版本的 RPM / DEB 软件包,做到真正的开箱即用。

这不是一个列表,而是一本百科全书
市面上不缺 PostgreSQL 扩展列表。PGXN 有一个,各种 Awesome List 也一大堆。但它们通常只给你一个名字和一句话简介。你想进一步知道这个扩展用什么语言写、用什么许可证、支持哪些 PG 版本、在你的操作系统上有没有预编译包、怎么安装、有没有冲突扩展,往往还是得自己去折腾。
我做的这个目录不一样。点进任意扩展详情页,你能直接看到:
- 基础元数据:版本号、所属分类、开源许可证、开发语言、GitHub 仓库、源码下载地址。
- 扩展属性:是否需要预加载、是否包含 DDL、是否支持
CREATE EXTENSION、是否trusted、是否可 relocate、默认安装到哪个 schema。 - 版本与构建信息:当前收录版本、支持的 PG 大版本、RPM 包名、DEB 包名。
- 全平台下载矩阵:14 个操作系统与架构组合下,对应的包、下载链接和包大小。
- 安装命令:针对
pig、dnf、apt三种方式,给出可直接复制粘贴的完整命令。 - 关联关系:相关扩展、依赖扩展、冲突扩展一目了然。

此外,我们还收录了 460+ 扩展文档,让你可以在一个地方直接浏览大量 PG 扩展的双语文档,而不是在分散的页面之间来回跳转。

464 个扩展,16 个分类
这 464 个扩展按功能被分成了 16 个大类。如果你之前听说过 PostgreSQL 可以做时序数据库、向量数据库、图数据库、文档数据库,甚至兼容 Oracle 和 SQL Server,那么现在你可以在同一个目录里把这些能力背后的扩展全部找出来,看到详细信息,再一行命令装上。

多维度浏览
除了按分类浏览,你还可以从不同维度切入这个目录。
按归属仓库
每个扩展归属于 PGDG、PIGSTY 或 CONTRIB 三类来源之一。PGDG 是 PostgreSQL 官方社区仓库,CONTRIB 是 PostgreSQL 自带扩展,而 PIGSTY 则是我额外打包收录和维护的部分。

按编程语言
你可以看到这些扩展分别是用 C、C++、Rust、Java、Python、SQL 还是纯数据文件实现的。尤其是近两年 Rust 扩展的增长趋势,在这里看得非常直观。

按开源协议
MIT、Apache 2.0、PostgreSQL、BSD、GPL、AGPL、Timescale License,不同协议对商业使用的影响各不相同,在技术选型时非常值得关注。

按扩展属性
哪些扩展需要修改 shared_preload_libraries 重启才能用?哪些是没有 SQL DDL 的“无头扩展”?哪些扩展之间有依赖或冲突?哪些包里包含多个扩展?这些都能在目录中直接看清楚。

按操作系统
在特定操作系统和 CPU 架构组合下,哪些扩展可用、哪些不可用、版本分别是多少,一张表就能说明白。

三件套:目录 + 仓库 + 包管理器
光有元数据目录还不够,配套基础设施同样重要。这次重做扩展目录,其实是一个系统性工程的一部分,整套体系包含三样东西:
- 扩展目录:告诉你有什么、能不能用、怎么用。
- 扩展仓库:提供预编译好的 RPM / DEB 二进制包,通过 CDN 分发,不必自己编译。
- 包管理器
pig:屏蔽不同操作系统和 PG 版本的差异,一行命令完成安装。
这三样东西配合起来,把“找扩展、选扩展、装扩展、用扩展”的完整链路打通了。
一些数字
下面是这套扩展百科全书和配套仓库的一些统计数据。




为什么要做这件事
做这个扩展目录,表面上是在做一个文档网站,实际上是在做 PostgreSQL 扩展生态的基础设施。
PostgreSQL 扩展生态的现状长期是“有酒无杯”:好东西很多,但发现、安装、使用的门槛太高。一个 DBA 想用 pgvector 做向量检索,或者用 pg_duckdb 跑 OLAP,他首先得知道这个扩展存在,然后得确认自己的操作系统上有没有包,再去处理各种编译、依赖和版本问题。这个过程中任何一环断掉,他都可能直接转头去用别的方案。
我想做的是把这个门槛降到最低:来这里看看有什么,挑你要的,复制一行命令,装上就能用。
每个扩展详情页,都是一个完整的 one-stop shop。你不需要再去 GitHub 翻 README,不需要去 PGXN 找包,也不需要猜操作系统兼容性。所有信息汇聚在一个页面里,中英双语,对国内外用户同样友好。
怎么用
如果你本来就会折腾 PostgreSQL,只是想在 PGDG 仓库之外额外安装一些“官方仓库”没有的扩展,那么直接添加 Pigsty 的 APT / DNF 仓库即可。pig 包管理器可以把这个过程大幅简化,但它并不是强制依赖。
如果你压根不想操心这些细节,也可以直接使用 Pigsty PostgreSQL 发行版。它的 rich 模板已经默认准备好了绝大多数常用扩展,你只需要按需启用即可。
完全开源
顺便一提,这个网站和扩展元数据本身也是完全开源的。如果你想自己保存一份副本,或者复用这套数据,直接去 pgsty/pgext 仓库就可以了,省得再自己写爬虫解析。如果你发现了扩展信息、元数据或文档中的错误,也欢迎直接提交 Issue 或 Pull Request。

附:Extension for Everyone
原稿末尾还附了一张相关主题演讲的海报,这里一并保留下来。

小结
扩展是 PostgreSQL 的灵魂,而这个目录,就是灵魂的索引。
464 个扩展,16 个分类,14 个操作系统,5 个大版本;中英双语;元数据、下载链接、安装命令、使用说明汇于一处。这件事的目标很简单:让 PostgreSQL 的扩展生态更容易被发现、更容易被安装,也更容易真正用起来。
如果你发现了有趣的扩展,或者对这套目录和仓库有任何建议,欢迎告诉我。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
8 - 464个扩展开箱即用:新版 PG 扩展目录发布
今天老冯又让 Claude Code 干了一件大好事 —— 做了一个全新的 PostgreSQL 扩展目录,就放在 pigsty.cc/ext 这里。
说起来,这已经是第五版了。兜兜转转一大圈,又回到了第一版使用的 Hugo + Docsy 框架,重新融合到 Pigsty 主站。这个过程本身就是个故事,后面再聊。先说说这一版到底做了什么。

不只是有包,还要有文档
之前的扩展目录,核心功能是告诉你:这个扩展叫什么、元数据在哪里、二进制包怎么下载、一键安装怎么搞。你装好了就行,至于怎么用 —— 自己找文档去。
这次不一样了。在 AI 的帮助下,我们开始系统性地收集并翻译这 464 个扩展的文档,目标是让你在一个地方就能看到所有扩展最关键的使用信息。
具体来说,分两种情况:
对于文档体量巨大的"巨无霸"扩展,我们会建立专门的子站点来做翻译。比如 Citus、TimescaleDB、PostGIS 这几个,文档量本身就相当于一本书,值得单独对待。
对于大多数轻量级扩展,情况其实很简单 —— 它们的全部文档往往就是一页 README。比如 pgvector,作为 PG 生态中最炙手可热的向量数据库扩展,文档就一页纸;

再比如 pg_repack,这个在线治理表膨胀的运维利器,文档也就是一页 Markdown。

我们要做的,就是把这些 README 统统收集起来,嵌入到每个扩展的详情页面中。你不用再到处跳转、翻 GitHub,在一个集中的地方就能查阅所有扩展的核心文档。对于特别大的扩展,我们也会把信息索引聚合起来,让你有一个权威可靠的参考入口。
目前 pigsty.cc 已经完成了 PgBouncer、pgBackRest 和 Patroni 的文档翻译。后续所有扩展 —— 包括 PostgreSQL 内核本身 —— 都会逐步推进并持续维护。
这也是我们的一个愿景:成为 PG 生态中关键信息的可靠来源。
说实话,很多时候我做"正活"剩下的 AI Token 额度没烧完,就顺手拿来填这些空,算是一种兜底,也算在做公益。
同时对 Agent 友好,对人类友好
接下来聊聊这个目录是怎么设计的。
虽然技术栈兜了一圈又回到 Hugo + Docsy,但在 Claude Code 的加持下,纯静态网站也能做出非常出色的效果。设计上,老冯遵循一个核心原则:同时对 AI Agent 友好,对人类读者友好。
对 Agent 友好,意味着网页的源码是开源的、采用 Markdown 格式,而且有一个硬性要求:减少杂音。Markdown 里不应该混入大量原生 HTML 短代码或格式噪声,否则会给 Agent 的解析和阅读制造很大障碍。
对人类读者友好,意味着要把信息高效组织为美观的可视化形式,让人能直观地发现问题、聚焦关键信息。

举个具体例子:这一版我们做了一个很实用的尝试 —— 将所有扩展融合进一张大表格。在特定的 PG 版本和操作系统组合下,你可以通过单元格直接看到有多少个可用的包、来自哪个仓库,点击即可下载,非常方便。
但是老冯并没有去用很复杂的 HTML 来实现,依然用的是标准的 Markdown 格式,只是在外面套了一层短代码进行必要的内容转换。这个在 Hugo 编译的时候进行必要的内容转换,然后通过定制的 CSS 格式,让它呈现出可观的效果。

同时我们这次也提供了一系列分门别类的列表索引,从不同维度展示扩展的属性信息,方便快速检索定位。站内搜索也比之前的版本好用了不少。







另外,这次我们还将一些 PG 内核分支独有的扩展也收录了进来:

五个版本,兜兜转转回到原点
最后聊一个不那么技术、但挺有感触的话题:文档框架的选型。
这个扩展目录从第一版到现在,前后经历了五个版本:
1.Hugo + Docsy(初版,融合在 Pigsty 主站)2.Docsify3.Next.js4.Hugo + Hextra(独立站点 pgext.cloud)5.Hugo + Docsy(现在,回归 Pigsty 主站)
中间那个独立站点 pgext.cloud,因为没有备案、挂在 Cloudflare 上,有国内用户反馈访问不稳定,怀疑被墙。思来想去,还是老老实实用备案过的域名来做这件事。
第一版:基于 Hugo + Docsy (和这次一样)

第二版:基于 Docsify
第三版:基于 Next.js + Fumadocs
后来实在受不了动态网站的一堆破事,回归静态网站了。
第四版:基于 Hugo + Hextra
Hextra 是另一个轻量化的,类似 Fumadocs 的主题。我很喜欢,它对于小型项目来说非常合适,比如翻译书什么的。但是对于大型文档站点来说还是有些力不从心。但是老冯的几本书,教程,小项目都很喜欢用这个框架。
这次挂在了独立站点 pgext.cloud 三,因为没有备案、挂在 Cloudflare 上,有国内用户反馈访问不稳定,怀疑被墙。思来想去,还是老老实实用备案过的域名来做这件事。
第五版: Hugo + Docsy

最终的结论其实很简单:
如果你要做静态文档站,选 Hugo 就行了。 Docsy 是 Google 出品的主题,Kubernetes 和 etcd 的文档都在用,基本功扎实,搜索好用,结构清晰,到现在还在活跃更新。轻量级的场景可以用 Hextra,重量级的就上 Docsy。如果需要做内容丰富的动态网站,Next.js 可以考虑,但它有时候确实挺重的。
Hugo 这个框架我用了快十年,从来没让我失望过。折腾了这么多新玩意,最后发现六七年前第一次选的框架就是最合适的选择。这大概也印证了一个道理:扎实的 Boring Technology 才是最好的。 网站不在于做得多炫酷,而在于里面的信息有没有价值。内容为王,始终没变。
你要说这些折腾的时间拿去做视频教程、写实战案例,是不是更有价值?也许吧。但折腾一圈回来,你知道了有哪些选择、它们各自的利弊权衡,提升了自己的 Web 设计经验与品位 —— 这本身就是一种收获。
谁说得准呢?折腾本身,也蛮有乐趣的。

归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
9 - 立足中国,面向全球的 PostgreSQL 发行版
大家好,我是冯若航,Pigsty 的作者,独立开源贡献者。 今天我想和大家聊一个话题:如何打造一个立足中国,面向全球的 PostgreSQL 数据库发行版。
这个标题听着有点大,但我想说的很简单:PostgreSQL 已经赢了,问题是 —— 我们中国开发者在这场胜利中扮演什么角色? 是旁观者,还是参与者?是跟随者,还是引领者?
数据库内核之争已经尘埃落定,真正的竞争将会发生在数据库发行版上。 而在这个关键的机会窗口里,我们应该凝聚生态合力,打造一个全世界开发者都愿意使用的基础设施,数据库世界中的 Ubuntu / Deepseek。
WHY — 为什么
PostgreSQL 已经成为数据库领域主宰者
PostgreSQL 已经赢了 —— 这个观点有着非常扎实的数据支撑。
Stack Overflow 开发者调查 显示,专业开发者中 PostgreSQL 的使用率达到 58.2%,甩开第二名 MySQL 18.6 个百分点,而且这个比例还在加速增长。 从新开源项目,AI SaaS 到 OpenAI 这样的独角兽,PG 已经成为新项目的标配 “默认” 数据库。

无论 DB-Engines 的数据库热度指数,还是 JetBrains 的开发者调查 都得出了相似的结论。 如果这些社区调查还不够,我们再看看资本市场的动向。
2025 年,PostgreSQL 生态发生了两起标志性收购案: Databricks 斥资约 10 亿美元收购了 PostgreSQL 初创公司 Neon,而 Snowflake 则以 2.5 亿美元收购了 Crunchy Data。 两大数据平台巨头通过收购杀入 PostgreSQL 的 OLTP 市场——他们选的不是 MySQL,也不是自研新库,而是直接押注 PostgreSQL。

各大云厂商同样在 All in PostgreSQL:AWS 的新品 Aurora DSQL,Azure 的新品 HorizonDB,GCP 的 AlloyDB,这些云上创新产品都是 PostgreSQL 独占。 PG 的胜利不仅仅是技术上的胜利,更是商业上的胜利。全球最聪明的钱,都在往 PostgreSQL 生态里涌。选择 PostgreSQL 就是选择了未来!
中国在PG开源生态中并没有多少参与感
遗憾的是,在 PostgreSQL 全球狂飙突进的过程中,中国开源的存在感却非常弱。 在这幅波澜壮阔的版图上,很难找到几样醒目的 “Made in China”。我们在见证 PG 巨大胜利的同时,却几乎缺席了这场盛宴。
此前的 PostgreSQL 社区内核 Committer 列表里,没有一位中国人。 而在开源项目方面,老冯搜集了由中国公司或者中国开发者主导的 PG 开源项目,结果发现 Star 数最多, 影响力最大的竟然是老冯这个数据库个人开发者的 Pigsty 。我一方面感觉很自豪,另一方面也感觉很荒诞。

| 项目 | Star | 简介 |
|---|---|---|
| pigsty | 4.3K | 开箱即用的PG发行版 |
| PolarDB PG | 3.1K | 阿里云 PolarDB 开源内核 |
| pgvector.rs | 2.1K | Rust 编写的PG向量扩展 |
| VectorChord | 1.4K | 下一代 Rust PG 向量扩展 |
| TBase | 1.4K | 腾讯云 PG 内核 |
| Cloudberry | 1.1K | Hashdata 的开源 Greenplum 2.0 |
| IvorySQL | 960 | 瀚高主导的 Oracle 兼容内核 |
| openGauss | 751 | 华为主导的早期 PG 分叉 |
| openHalo | 626 | 易景开源的 MySQL 兼容 PG 内核 |
| zhparser | 798 | 使用 scws 的PG中文分词扩展 |
| duckdb_fdw | 393 | 李红艳开源的 DuckDB 包装器 |
| pg_jieba | 392 | 使用结巴分词的 PG 中文分词扩展 |
| VectorChord-bm25 | 314 | PG 原生的 BM25 排序索引算法 |
| pg_roaringbitmap | 263 | PG 中的 RoaringBitmap 位图 |
我这两年参加了几场 国际 PostgreSQL 会议,感受很复杂。 去年 PG 开发者大会里,我碰上了瀚高北美的 Grant Zhou 和 Carry Huang,富士通的 Zhijie Hou,再加上我,就没有别的中国开发者影子了。 今年 还碰上了 TensorChord 的朋友。放在几百人的大会里面,依然是不成比例的极少数。
中国有两三百个数据库产品,很多都是 PG 衍生。但在全球 PostgreSQL 生态里,几乎没有存在感。 我们的人才、我们的资金、我们的精力,都花在了重复造轮子上。当全球同行们正在奋勇创新,在资本市场嘎嘎乱杀的时候。 中国的数据库同行们却在泥潭中挣扎 —— 几百家国产数据库公司,只有四家在盈利,整个行业正在高速缩水凋亡。 这说明什么?说明我们在错误的方向上投入了太多资源,市场正在用脚投票。
我们需要思考如何破局:如何在 PostgreSQL 生态中找到一个切入点,做出像 Deepseek 这样有世界级影响力的东西
有这样的东西吗?有的,朋友们,有的。
数据库发行版大战拉开序幕
数据库内核之争已经尘埃落定,真正的战斗将会发生在数据库发行版上。 —— 这个判断来自对 Linux 发展历程的观察。
1991 年,Linus Torvalds 发布了 Linux 内核。但 Linux 内核本身是不能直接用的, 你需要有人把内核、工具链、软件包、配置脚本打包在一起,形成一个可以安装、可以使用的操作系统。这就是 发行版。
1993 Debian 年诞生,94 年 RedHat 诞生。之后服务端操作系统内核很快就收敛到了 Linux 上, 大家都用同一个内核,OS 世界的竞争很快就从内核层面转移到了发行版。
今天的 PostgreSQL,正处于当年 Linux 的位置上。

做过系统管理的朋友都清楚,真正的生产环境中几乎没有有人会从源码编译整个 Linux 内核和软件栈,而是直接选择一个发行版。 因为后者已经帮我们选好了内核版本、驱动与库,准备好了软件仓库和包管理器,带有文档手册与最佳实践,可以 开箱即用。
PostgreSQL 内核如今已经足够成熟强大了,如何把内核 + 扩展 + 高可用 + 监控 + 备份 + 安全等要素整合起来,形成一个开箱即用的完整解决方案,这件事成为了关键。 PostgreSQL 内核称王,发行版诸侯争霸。谁会成为数据库世界的 Debian / Ubuntu / RedHat,群雄逐鹿,犹未可知。

事实上,目前在全球范围内,围绕 PostgreSQL 已经出现了一些“准发行版”的雏形。最有名的就是 Supabase。 它把 PostgreSQL 内核与几个扩展和开源生态组件打包起来,加上UI封装成一个后端即服务 (BaaS) 平台。 从本质上看,这就是一个 PostgreSQL 发行版!钉死了 PG 中的 Android 生态位.
一家成立不到五年的 PG 发行版创业公司,估值高达 50 亿美元; 而 PostgreSQL 内核贡献的老大哥 EDB,成立近20年估值才 10~20 亿美元,这足够证明很多事情了。
这对于我们而言既是挑战,更是机会。在这个时间窗口里, 我们完全有机会打造一个由中国团队主导的 PostgreSQL 开源发行版,服务全球用户,抢占新的制高点。 如果我们再错过这一次的机会窗口,我们可能又要在下一个时代继续扮演追随者的角色。
HOW:我是怎么做的?
但在讲故事之前,我先亮个底牌 —— 我不是来画饼的,我已经做出来了。
Pigsty,一个 PostgreSQL 发行版。从下载量和网站 UV 看,用户大概小十万,中国一半,海外一半。GitHub Star 在中国 PG 生态项目里排第一。

要是拿来和 Supabase 这种50亿美金的巨无霸比呢,差距确实很大,Supabase 的 Star 数量和用户量都是 Pigsty 的 20 倍。
Supabase 其实属于 2C 的 “Android”,而且也被老冯偷了家,目前 Pigsty 是极个别可以直接 自建生产级 Supabase 的开源方案。
但这个生态允许错位竞争,可以同时出现多个赢家, 如果看 Linux 原生 PG RDS 发行版 这个细分赛道,Pigsty 拿第一当仁不让。 就算拉上 EDB、Crunchy 这些大厂搞的十几个 K8S 云原生 Operator 一起比,也算是打得有来有回。

至少我证明了:一个中国开发者,用正确的方法,也可以在 PG 全球生态里占有一席之地,拿到了一张决赛圈的门票。

Claude Opus 4.5: PG 生态发行版格局分析

Gemini 3 Pro: PG 生态发行版格局分析
老冯 2022 年开始全职创业做这个,差不多三年半了。技术储备从 2018 年就开始。 作为开源项目,有一些外部贡献者,但 99% 以上的代码和工作量,是我一个人完成的。 那么问题来了:一个人,怎么做到这些的?其实就是两句话,立足中国,面向世界。
立足中国:规模是最好的试炼场
什么是“立足中国”? 它不是一句口号,而是我们手中最有价值的资源 —— 规模与场景。
Pigsty 并不是在车库里凭空想出来的,它是在 探探 —— 中国第二大陌生人社交平台上孵化出来的。(PS. 这是个瑞典的创始团队) 在那几年里,我们要面对的是什么?是 250 万全局 QPS 的恐怖流量,是所有核心业务逻辑全跑在数据库存储过程里的极限架构,以及上百套大型物理机集群的高效监控管理。
就连现在独角兽之王 OpenAI 对于 PostgreSQL 的使用规模与深度,也没有达到当初我们所面临的挑战。 当时市面上的监控、高可用方案,在这种规模的冲击下,要么不够看,要么不好用。 没办法,逼着我们自己试,自己造,自己整合。 我们是在几百万 QPS 的高压锅里,在一个又一个故障和报警的锤炼下,把 Pigsty 打磨出来的。
这就是“立足中国”的真正含义: 中国拥有全球罕见的互联网规模和复杂场景。这里的海量用户高并发挑战,就是最好的炼丹炉。 如果一个方案能扛住探探这种级别的压力与复杂度,并解决好这些问题,那它放在全世界的其他场景下基本都是降维打击。
—— 立足中国,就是要用中国互联网场景独有的规模场景,打磨出世界先进的生产级方案。

面向全球:成为供应链的上游
那什么叫“面向全球”? 把文档翻译成英文,去海外发帖推广,那算不了什么。 真正的面向全球,是 让你自己成为全球软件供应链不可或缺的一环。而想要走向全球,你需要关注的是开发者的体验与需求。

差不多做到 2023 年,Pigsty 运维层面已经很完善了。 高可用,备份恢复,监控系统,离线部署,IaC 大规模管理全部整合到了一起,可以无需容器在主流 Linux 上一键交付。 但我隐隐觉得哪里不对,老冯一直站在 DBA 的视角,做了很多可靠性、可观测性,质量与易用性上的工作 —— 但我忽视了开发者的核心需求 —— 功能特性。

我意识到:扩展才是 PostgreSQL 最大的价值所在。MySQL 想加向量搜索,折腾很久效果还不好。 PG 呢?一个社区开发者写了 pgvector,几个扩展一起赛马,直接把这个赛道卷没了,这就是可扩展架构的威力。
去年我写了一篇文章《PostgreSQL 正在吞噬数据库世界》,发到 Hacker News 火了,传遍整个 PG 社区。 核心观点就是:PG 能拳打 Oracle、脚踢 MySQL,靠的是极致的可扩展性和繁荣的扩展生态。
于是我开始做扩展仓库。一开始想借力,等生态里其他项目做完再集成。 等了几个月发现等不来,就自己干了。先编译十几个,然后几十个,然后一百多个。 做着做着发现:PG 生态里能打的扩展就几百个,官方仓库提供一百出头, 而我凭一己之力把这个数字推到了 437 个。

这个仓库覆盖 14 个 Linux 发行版、x86 和 ARM 两种架构、6 个 PostgreSQL 大版本。 仓库里有六七万个 RPM 和 DEB 包。很多扩展得改代码才能编译通过,我前后修了几十个。 想借力借不到只能自己干,反而干出了壁垒。最费工夫的苦活,成了最坚固的护城河。 但老冯也不会藏着掖着,敝帚自珍,而是将这个扩展仓库对公众与同行免费开放。

让我没有想到的是, 现在不仅仅是 PG 终端用户在用 Pigsty。 国外的数据库发行版项目,甚至是一些商业数据库公司,开始直接使用 Pigsty 的扩展仓库作为他们的上游源。
以前,我们是下载别人的代码,用别人的源。 现在,是一个中国开发者维护的仓库,成为了国际数据库同行的上游基础设施。 我们不再只是旁观者或者消费者,我们成了供应商,我们嵌入到了全球 PG 的供应链里。

这是真正的出海:不是去别人的地盘抢饭吃,而是让别人做饭的时候,用你的大米。 用这种方式,老冯的发行版开始成为了 PostgreSQL 生态的一块基础设施,成为全球软件供应链的一个节点。
有了从零到一的突破之后,中国的 PG 生态开源软件也能够更容易的走向国际。 在老冯的 Pigsty 仓库中,目前还分发三款来自中国的 PostgreSQL Kernel 分支 —— IvorySQL,PolarDB,OpenHalo,以及一些中国开发者的扩展与工具。

邀请
一个人做到现在这个程度,真的很不容易。但如果想要更进一步,打造出一个像 Ubuntu 这样的,全球主流的 PostgreSQL 发行版。 那就绝非一人能成了,需要众人拾柴火焰高。所以今天,我想借这个机会,向在座的各位发出邀请。共同参与到这样的事业中来。
面向用户的邀请
对于用户来说,你可以通过使用 Pigsty 免费获得企业级质量的本地 RDS 服务,免去手搓HA,编译安装配置等诸多烦恼,一步到位完成生产数据库自建,开箱即用。
我们邀请您在新项目中尝试 Pigsty —— 反正一行命令就能部署,不满意可以随时换掉。如果愿意向朋友推荐,写下使用心得,投稿博客或者视频,那对于项目来说也是巨大的贡献。
面向数据库厂商的邀请
对于数据库厂商来说,我想说的是,如果你们交付给客户的还是一个裸的 RPM / DEB 包,现在你可以选择用 Pigsty 交付一套完整的生产级基础设施。 Pigsty 可以成为你们的交付载体。你们专注做内核、做特色功能,Pigsty 帮你们解决周边生态的问题。这是双赢的合作。已经有好几款PG内核分支 通过 Pigsty获得了完整的 RDS 能力。

作为诚意,原本 AGPLv3 许可证的 Pigsty 本体也将在下个大版本中使用更宽松的开源许可。而像 PG 扩展仓库,PIG 包管理器的的全部代码与基础设施都以 Apache 2.0 许可证开源。
面向开发者的邀请
对于扩展作者来说,PGEXT.CLOUD 是一个让你的作品触达全球用户的渠道。
你写了一个 PostgreSQL 扩展,怎么让用户用上?自己编译打包适配十几个不同的 Linux 发行版? 自己去触达全世界的 PG 用户?如果你有这样的烦恼,也许老冯可以帮到你。
结语
最后,我想用一句话来总结今天的演讲:
与其在两百多个国产数据库里内卷,不如一起打造一个全世界都想用的 PostgreSQL 发行版。
PostgreSQL 已经赢了。现在的问题是,我们中国人要不要参与这场胜利,以及以什么姿态参与。我选择的姿态是:拥抱 PostgreSQL,做一个发行版,立足中国,面向全球。
这条路我已经走了 7 年,即使是一个人,我会继续走下去。但我希望不是一个人走,而是有更多的人一起前行。
谢谢大家。

归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
10 - 聊聊开源软件供应链信任问题
昨天,老冯的一篇文章《从PG“断供”看软件供应链中的信任问题》收到一条评论, 评论者称是高校开源镜像站的管理员(清华 TUNA),向老冯提出批评抗议,内容如下:
作为高校开源镜像站管理员,我想要提醒作者,文中“躺平”“没有担当”的措辞是很不负责任的、令人心寒的指控。

老冯看到评论之后也做了回复:
感谢 回复与评论,也感谢这些年 TUNA 以及国内各高校镜像站为开源镜像生态投入的时间和精力。我看到当时 TUNA 的 PostgreSQL 仓库已经恢复了和上游的同步,这一点先点个赞。
最初发现问题时,我用的是阿里云的 PostgreSQL 镜像。后来注意到 TUNA 上也存在同样的情况,就纯粹出于开源道义在 向 TUNA 邮件列表反馈问题,得到的是一句(本邮件列表是 TUNA 的邮件列表,与阿里云无关)与长期的沉默,这样的感受会体现在文章的情绪中。
回头看原文,用“躺平”“没有担当”这样带有明显的情绪色彩的字眼,放在 贵站身上 已经不准确,也容易被误解为在给志愿者贴道德标签,这并非我本意。如果这段措辞让一线维护同学感到不舒服,我在这里先说声抱歉。我已经 修改措辞 为更中性的说法,比如“长期未更新” / “不再维护”,避免伤到真正干活的人。
对于你提到的一点我是认同的:高校镜像站本质上是志愿者项目,没有法律或合同意义上的承诺。不再维护这件事无法在法律和道德上苛责什么,这一点在文章里也多次强调过。但从下游用户的角度看,PGDG 切断 rsync 之后,国内主流镜像在相当长一段时间里停留在几个月前的版本,对很多只会照着“推荐镜像源”配置的用户来说,客观效果就是供应链中断,这是实实在在的风险,缺乏维护损耗的是用户对镜像站的信任。
我的感想是:在没有服务承诺的前提下,把高校镜像当成关键生产基础设施,是一种错误的依赖方式。我自己的做法是不再把别人的开源镜像站当成上游,而是自建 PGDG 镜像,自己掌握软件供应链;再次感谢你把维护者的视角和感受说出来。这次讨论至少能帮更多用户搞清楚:开源软件镜像站能做什么、不能指望它做什么,这本身就是有价值的。
老冯的感想
收到消息后呢,我去清华 TUNA 源上看了一眼,PostgreSQL 仓库里已经有最新的 PG 18 的包了,不过 “Last Update” 时间戳还是 2025-05-16,应该是手工同步的。 总的来说是件大好事,除了老冯的 PIGSTY 仓库 之外,国内总算又多了一个能提供相对及时 PGDG 镜像的节点,这一点我要为 TUNA 点个赞。

其实在老冯的 PG 发行版 Pigsty 里,原来使用的是阿里云的 PostgreSQL 镜像站,并没有直接从 TUNA 拉 PG 包。 “躺平”“没有担当”这些情绪上的评价,最初更多是冲着阿里云这种有资源的大厂去的 —— 云计算泥石流 的保留节目。 毕竟阿里云作为互联网大厂和本土云计算一哥,从开源攫取了巨大价值,搞个开源镜像站却长期不维护 PG 仓库,实属拉垮。 结果在这次风波里,反而是清华 TUNA 的同学先站出来表达了不同看法,这一点我也理解。

这里说一句公道话:不管是阿里云镜像站还是 TUNA 镜像站,我在原文里多次强调过 —— 作为免费的服务提供方,在法律和道德上确实没有义务去做这件“慈善”。 但这并不妨碍每个人对现实结果有自己的看法和评价。“躺平”“没有担当”是我当时的主观感受,现在回头看,用在高校志愿者身上,确实容易误伤人。 所以我已经把措辞调整为“停止维护”“长期未更新”这类事实性的表述,把情绪收回来,避免误伤一线维护的同学。
为什么老冯会有这种感觉呢?我在发现 全球镜像站出现同步问题 之后,第一时间就 给阿里云发邮件反馈了这个问题(当然阿里云现在还没修)。 同时,我也顺手看了一圈国内其他镜像站,发现清华 TUNA 镜像站也有这个问题,就在他们的邮件列表里发了一封提醒。 结果有同学回复说:“你发的这个是阿里云的问题,跟本站无关”。我解释这是所有镜像站共有的问题,然后就再没有任何回应。

大概又等了一个月左右,老冯实在是不想等了,就自己搭建了 PGDG 中国区域的镜像仓库,放在腾讯云上,和 Pigsty 自己的仓库放一起。 移除了对阿里云 PostgreSQL 镜像站的上游依赖,至少在 PostgreSQL 制成品分发上,实现了完整的自主可控供应链。 老实说,如果不是因为国内镜像站在这件事上的整体表现,老冯可能也不会这么快去做这件事。
老冯嘴臭惯了,对云厂商说话一向不太客气,但这不意味着我不理解志愿者的难处 —— 尤其是对于高校开源志愿者,整体上我觉得应该多一点呵护,少一点道德化的指责,这也是我后来主动调整措辞的原因。
开源与信任
实际上老冯自己也刚刚经历过类似的事情。我也维护了几个开源项目,还有不少 PostgreSQL 生态里的工具。 比如说 pg_exporter —— PG 的 Prometheus 指标导出器,有一些 PG 厂商也在用。 前天我才注意到,9月份有人在上面提了一个 Issue 写到:
你好,虽然我知道这是一个开源项目,但我一个月前提交的两个问题至今仍未得到任何回应,这实在令人失望。 我对 pg_exporter 1.0 版本以及 PG 邮件列表上的公告都充满期待,甚至考虑过贡献代码。 但我不愿把希望寄托在一个维护者缺席的项目上。希望这只是暂时的,也希望他一切安好。 我没有任何怨言,衷心祝愿这个项目和维护者一切顺利。

老冯九月份在新疆自驾了一个月,没怎么用电脑,Issue 点开看过但后面就忘掉了。 “缺乏维护” 导致这位用户对老冯的开源项目失去了信任,而他本来也许可以成为项目的贡献者。辜负了他的信任与期待,确实让老冯感到非常遗憾与愧疚。 所以我就放下手头的事儿,把他提的问题修了一遍,然后发布了一个新版本 1.0.3。
将心比心,当我发现我所依赖的上游镜像站出现问题,而你反馈了也没人理、没人修时,我自己也会有这位用户一样的感受:
“我不愿把希望和信任寄托在一个维护者缺席的项目上”。
软件供应链
在那篇《从PG“断供”看软件供应链中的信任问题》中,老冯提出过一个观点:
“开源” 确实并不要求你向用户提供可靠稳定的二进制制成品,但真正重要的不是开源,而是信任。 开源只是构建信任的一种形式,持续的投入,交付的承诺,专注的热情,面对问题的担当。 想要成为值得信赖,受人尊敬的社区参与者,有许多东西比丢一份源代码到仓库要重要得多。
把开源镜像站办起来,说好听一点,也是某种公共慈善。这位管理员同学的委屈我是能理解的: “我们又没拿报酬,还要扛合规和安全风险,牺牲个人时间来维护。你不说谢谢就算了,怎么反过来用‘躺平’‘没有担当’这样的词来说我们?”
这里有一个现实却不太好听的点:对维护者而言:“我没收钱,所以我没有义务”,在内心是一个很自然的防线; 但对用户而言:只要你把服务挂在公开的地址上,大家自然就会把它当成“某种可以依赖的基础设施”。这种期待不甚合理,但是真实存在。
镜像站与普通开源项目有一个重要区别:它处在软件供应链的中间 —— 是从上游到下游的通路,直接影响生产环境, 而不像单纯开源项目那样 “我写个工具,你爱用不用”。
而供应链天然就会出现分层:
- 有可靠的,有不可靠的;
- 有愿意给出承诺、出 SLA 的,也有只愿意尽力而为的;
- 有愿意把“这事算我头上”的,也有明确表示 “别指望我” 的。
做到好、长期维护、有清晰的预期管理,就会积累声望、信任、影响力,成为别人可以安心依赖的关键节点; 做不好,交付过时或不可靠的结果,自然也要面对用户信任的流失。
当这位同学写下:“与商业镜像站不同,国内全部的高校镜像站都没有任何服务承诺和保证” 这句话本身从维护者视角看,非常诚实。 但换一个视角 —— 生产运维负责人听到这句,大概会在脑子里立刻画一个叉:“没有任何服务承诺和保证,那就没法出现在生产供应链上游。”
所以,这篇文章不是要去指责镜像站 “没有担当”,而是要提醒下游用户 —— 在严肃的生产环境里,你不能依赖一个明确说“我不提供任何保证”的上游。
质量与承诺
清华 TUNA 提供的很多镜像服务是有价值的。比如 pypi 和 homebrew 镜像,我个人电脑上就一直在用,它们完全胜任“加速访问”的角色。 在 Pigsty 的早期版本里,我也用过部分 TUNA 的 PostgreSQL 镜像。后来遇到过几次莫名其妙的 403 封禁,这对自动化部署来说不太友好,于是就全部改成阿里云的镜像了。
整体上看,阿里云镜像站过去的表现是比较稳定可靠的,直到这次 PGDG 切断 rsync 之后,PG 仓库一直停在几个月前的版本,至今还没有修复。 这件事客观上削弱了我对它的信任,所以我选择自己托管 PGDG 镜像,把这部分供应链从它身上剥离出去。 操作系统层面的镜像,我目前仍然在用阿里云。如果哪一天阿里云在 Linux 系统镜像上的表现也开始频繁翻车,那我也很可能会考虑自建 Rocky / Ubuntu / Debian 的镜像源。
在这件事情上:
- 清华 TUNA 管理员很坦率地表示:高校镜像站不提供服务承诺。这个立场本身没有问题,但下游看到这句话,自然会据此调整对你的使用边界;
- 阿里云没有明确说,但从过往表现来看,我们可以暂时把它当成“部分负责的大厂”:如果继续出问题,那老冯回去催它/批评它,或者在自己的体系里换掉它;
- 老冯的 Pigsty / PGDG APT / DNF 仓库,会明确给出承诺:如果仓库出问题,我会去修;如果修不好,那我自己信誉扫地,对付费客户来说,这也意味着 SLA 违约责任。
镜像站、仓库、发行版,这些都是“基础设施中的基础设施”。是否愿意为自己的服务说一句“出了问题算我头上”,决定了你在这个生态里的角色 —— 只是好心的志愿者,还是真正能被依赖的关键节点。
当高校镜像站把丑话说在前面,下游又应当如何自处?当别人告诉你“别指望我”,最稳妥的回应永远是“那我自己来”。
广告时间
写文章不打广告约等于没写,也许老冯提供的服务正好能帮到你。以下三个国内镜像仓库,免费对公众提供服务: 这些仓库提供 Cloudflare 全球版本与国内云墙内版本,可以方便的使用 pig / apt / dnf 启用。 更详细的介绍请参考 PGEXT.CLOUD 软件仓库说明。
PGDG镜像
定期同步全球 PostgreSQL 开发组官方软件仓库(el 7-10, debian 11-13, ubuntu 20-24) 最近同步于今天,每周更新。文中原有的 APT/YUM 目录入口现已停用;当前镜像地址与启用方式请参见 Pigsty 软件仓库文档。
PIGSTY PGSQL
PIGSTY PGSQL 仓库:提供 几款不同风味的 PG 内核分支 (PolarDB, IvorySQL, Babelfish, OrioleDB, OpenHaloDB, Percona TDE, Supabase,… ) ,与 PGDG 官方仓库配合使用,提供多达 437 个 PG 扩展插件 与生态常用工具。支持 14 个 Linux 发行版大版本。
文中原有的 APT/YUM 目录入口现已停用;当前镜像地址与启用方式请参见 Pigsty 软件仓库文档。

PIGSTY INFRA
提供各类数据库相关工具,Grafana,Prometheus,以及 Exporter 可观测性全家桶
文中原有的 APT/YUM 目录入口现已停用;当前镜像地址与启用方式请参见 Pigsty 软件仓库文档。
| DBMS | Prometheus | Grafana | |||
|---|---|---|---|---|---|
| IvorySQL | 4.6 | prometheus | 3.7.3 | grafana | 12.3.0 |
| etcd | 3.6.6 | pushgateway | 1.11.2 | loki | 3.1.1 |
| minio | 20250907161309 | alertmanager | 0.29.0 | promtail | 3.0.0 |
| mcli | 20250813083541 | blackbox_exporter | 0.27.0 | vector | 0.51.1 |
| kafka | 4.0.0 | VictoriaMetrics | 1.129.1 | grafana-infinity-ds | 3.6.0 |
| duckdb | 1.4.2 | VictoriaLogs | 1.37.2 | grafana-vmlogs-ds | 0.21.4 |
| ferretdb | 2.7.0 | pg_exporter | 1.0.3 | grafana-vmetrics-ds | 0.19.6 |
| tigerbeetle | 0.16.60 | pgbackrest_ex… | 0.21.0 | grafana-plugins | 12.0.0 |
| juicefs | 1.3.0 | node_exporter | 1.10.2 | ||
| dblab | 0.34.2 | keepalived_exp… | 1.7.0 | UTILS | |
| vray | 5.28.0 | nginx_exporter | 1.5.1 | sealos | 5.1.1 |
| pig | 0.7.2 | zfs_exporter | 3.8.1 | rclone | 1.71.2 |
| vip-manager | 4.0.0 | mysqld_exporter | 0.18.0 | restic | 0.18.1 |
| pev2 | 1.17.0 | redis_exporter | 1.80.0 | mtail | 3.0.8 |
| promscale | 0.17.0 | kafka_exporter | 1.9.0 | genai-toolbox | 0.18.0 |
| pgschema | 1.4.2 | mongodb_exporter | 0.47.1 | sqlcmd | 1.8.0 |
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
11 - PG扩展云:解锁 PG 生态的全部潜力
PostgreSQL 拥有极为强大的扩展插件体系。 在 《PostgreSQL 正在吞噬数据库世界》中, 老冯已经阐述过 可扩展性 是 PostgreSQL 成功的核心要素。 举例来说,PG 有 GIS 领域的事实标准 PostGIS,向量数据库的瑞士军刀 pgvector,还有可以替代 ElasticSearch 的 pg_search, 以及使用 DuckDB 在 PG 内进行分析的 pg_duckdb / pg_mooncake 等等,这些扩展为 PostgreSQL 赋予了超乎想象的能力。 只有加装了这些扩展,PG 才能称得上是 “全盛完全体”。
然而,要在生产环境中可靠地编译、安装这些扩展插件并非易事,会有许许多的挑战。绝大多数扩展仅仅交付源代码,需要自己去摸索编译。 对于严肃的生产环境来说,源码编译和 Docker 镜像 往往也不是一个可行选项 —— 当你需要组合使用多个不同扩展,在不同服务器上精确安装相同版本,或者根本不想使用容器时,就会有各种问题。 还有一些非技术的挑战需要克服 —— 官方镜像站停止更新 ,以及国内网络环境受限导致无法下载。
不过,这些问题都被老冯一一攻克了!经过最近两三年无数日夜的努力,我很自豪地向大家介绍 PGEXT.CLOUD —— PG扩展云, 一次性, 一条龙,一步到位解决用户安装扩展,开发者分发扩展,厂商交付扩展的难题。
PGEXT.CLOUD
PG 扩展云(PGEXT.CLOUD)提供了以下三样基础设施,帮助用户更好的利用 PostgreSQL 扩展生态系统的协同超能力:
- 扩展目录 :一个在线网站,查阅 431 个扩展插件 的详细信息,找到满足您需求的插件。
- 扩展仓库 :获取预先打包的 RPM/DEB 二进制包,在 14 个 Linux 大版本 上可用
- 包管理器 :屏蔽复杂度与操作系统与架构差异,使用 pig 命令行工具一键完成所有步骤
只需几行命令,即可在 主流 Linux 系统 上原生安装多达 431 个 PostgreSQL 扩展,组合使用,发挥 PostgreSQL 的超能力。 如若不信,在全新的 Linux 服务器/容器环境中,下面三行命令就能让你安装 PG 18 官方内核与一些最强大复杂的 PG 扩展插件:
这几条看似简单的命令背后,其实隐藏了巨大的复杂度与工作量。支持 14 个 Linux 发行版、6 个 PG 主版本、431 个扩展插件所产生的排列组合,是一个近乎天文数字的挑战。
而在实现“丝滑”安装交付的过程中,还伴随着各种棘手问题 —— 庞大的数量,驳杂的质量,分发的限制,心智的负担。好在这些挑战现在都有了一个不错的答案。
无可比拟的数量
PostgreSQL 生态中拥有数量庞大的扩展,总数可能超过 1000 个。然而在官方 PGDG 仓库中,目前只提供了其中约 135 个扩展。 诚然,一些耳熟能详的插件(如 PostGIS、pgvector 等)包含在官方仓库里,但还有许多强大的扩展并未被收录 —— 例如近期炙手可热的 DuckDB-PG 融合扩展 pg_duckdb 和 pg_mooncake。老牌的 Plv8,还有 Supabase 自建所需的一系列 Rust 扩展。
官方仓库不收录这些扩展有许许多多的原因 —— 比如 YUM 仓库的维护者 Devrim 就表示,绝对不会让 Rust 写的 PG 扩展进入仓库中。 而像 plv8,pg_duckdb 这样一编译一个小时的扩展巨无霸,毫无疑问也会显著拉高仓库维护的成本,所以老冯也完全能理解。
老冯曾经寄希望于 Tembo 的包管理器 trunk,或者 pgxman 之类的东西可以解决这些问题,不过似乎最后还是不自己动手上。 (比如 tembo 就已经跑路去干 AI DBA 去了)。而这一干就一发不可收拾,一下子就干成了 PG 生态里最大的扩展目录与仓库。
简单来说,这个扩展目录目前收录了 431 个扩展,抛开 PG 自带的 71 个扩展总共 360 个。 PGDG 官方仓库维护了 144 个 EL 扩展和 105 个 Debian 扩展,而老冯的 PGSTY 维护了 260 个 EL 扩展与 241 个 Debian 扩展, 占到了总数的 72% 左右,哈哈,这可真是以一己之力撑起了大半边天。
| 分类 | All | PGDG | PIGSTY | CONTRIB | MISS | PG18 | PG17 | PG16 | PG15 | PG14 | PG13 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ALL | 431 | 150 | 260 | 71 | 0 | 396 | 419 | 421 | 424 | 409 | 384 |
| EL | 425 | 144 | 260 | 71 | 6 | 385 | 412 | 415 | 418 | 406 | 380 |
| Debian | 417 | 105 | 241 | 71 | 14 | 384 | 407 | 407 | 410 | 398 | 369 |
良莠不齐的质量
当然,光有数量是不行的,更重要的是质量。PGDG 的 YUM 仓库有许许多多的 “坑”: 某个发行版和 PG 的组合可能漏掉了,不同 PG 大版本的扩展版本不一致,老冯在这里可没有少给 PGDG 仓库擦屁股。
更大的问题在于部分扩展缺乏及时维护。当 PostgreSQL 推出 16、17、18 等新版本时,一些扩展因为无人更新而无法兼容新版本,甚至直接导致崩溃。 这两年来,老冯 修复了近百个“趴窝”的扩展。例如,最近几乎所有重要的 Rust PG 扩展,在老冯的推动下都已升级到最新的 pgrx 0.16.1 框架,并支持 PG 18。

可以说,目前目录里的这些扩展,即使原作者弃坑不干了,老冯也有信心接手维护,持续为新版本保驾护航。 当然,确实有极个别规模太大,难以抢救且作者失联的扩展,老冯也只能无奈摊手(age,hydra)。
也许你会好奇,老冯一个人是怎么维护这么多扩展的?说起来,这还真是多亏了 Claude Code。 Opus 4.1 干这个可真是一把好手,通常我只要念出正确的咒语,然后 Review 一下,大部分情况下问题就迎刃而解了,哈哈!
如何分发扩展
光解决扩展的编译打包还不够,如何高效地将扩展分发到用户手中,同样面临诸多挑战。 首先需要维护一个 APT 仓库和一个 YUM 仓库,确保不同系统的用户都能方便获取软件包。 PGEXT.CLOUD 默认通过 Cloudflare 提供全球 CDN 加速,但 Cloudflare 在中国大陆访问缓慢,因此我们专门搭建了位于国内的镜像站来提供高速下载。
虽然,打包构建是一项相对冷门稀缺的技能,但建立自有仓库镜像并不是最棘手的问题。 更大的难题在于:除了 Pigsty 自己的扩展仓库镜像,俺还需要维护 PostgreSQL 官方 PGDG 仓库的国内镜像!
在我之前的文章 从PG“断供”看软件供应链中的信任问题 和 卡脖子:PostgreSQL切断镜像站同步通道 中, 我曾提到:PostgreSQL 官方 PGDG 仓库自今年5月起停止了 ftp/rsync 同步通道,这导致全球范围内的大部分镜像站从那时起就不再更新了。 对于海外用户来说影响尚不明显,但对于无法自由访问外网的中国大陆用户而言,这意味着如果不翻墙就无法获取 PG 的最新软件包。 大家常用的阿里云、清华 TUNA 镜像源目前都停留在 2025-03-31 的版本,仓库连今年 9 月发布的 PG 18 都影子无踪。

目前,能持续更新 PGDG 仓库镜像的我所知道也就只有老冯维护的 Pigsty、俄罗斯的 Yandex,以及欧洲 Xtom。 我每周都会手动同步上游 PGDG 仓库,确保国内用户也能拿到最新的更新。 顺带一提,老冯还在 PGDG 镜像里帮 PGDG YUM 仓库修复了一些陈年旧 bug(比如 patroni 3.0.4 这个钉子户版本)。
总而言之,如今只要你使用主流 Linux 发行版,无论身在国内还是海外,都可以通过 PGEXT.CLOUD 享受丝滑顺畅的 PostgreSQL 及其扩展安装体验,再也不用为网络和环境问题操心。

PG扩展维基百科
扩展插件如此众多,对于普通用户来说,安装使用时难免会被各种配置、源站、镜像等细节搞得头大。 许多初学者只是想用上 PostgreSQL 及其扩展,这些繁琐细节实在没必要成为绊脚石。 这正是老冯在仓库之外,又额外提供 扩展目录 和 包管理器工具 两项服务的原因。

PGEXT.CLOUD 的扩展目录汇集了前述 431 个扩展的详细信息。 我们为每个扩展整理了元数据、在各操作系统和 PG 版本上的可用性矩阵,以及完整的安装、配置与加载使用说明。


我们还按功能、许可证、开发语言等多个维度对扩展进行分类索引。一些重要扩展甚至配有专门的说明章节和教程。PGEXT.CLOUD 的目标很明确 —— 打造 PostgreSQL 扩展界的维基百科,让用户对可用的扩展“一览无余”,也为开发者提供展示自己作品的平台。
简单易用命令行
当然,更令人兴奋的是,我们还提供了简单易用的命令行工具 pig。 这个用 Go 语言编写的小巧工具(仅 4 MB),将 PostgreSQL 的安装和扩展交付过程简化到了极致。
例如,只需下面三行命令,就可以分别完成下载 pig、配置仓库以及安装 PG 内核和扩展插件:
无论您使用的是哪种 Linux 发行版,配置了什么软件源,所处地域网络如何,使用 dnf/yum 还是 apt,这个工具都能替您处理好所有细节。
值得一提的是,pig 并非另起炉灶造轮子,而是对现有 Linux 包管理器的 “一层薄皮封装”(PiggyBack)。 换言之,您依然可以使用经典的 apt/yum 来直接访问 PGEXT.CLOUD 的软件仓库 —— pig 只是让这一切变得更简单,但并不是不可替代的强制依赖,更不会引入任何供应商锁定。
它不关心你运行在什么 Linux 上,配置了什么仓库,在什么区域,用的是 dnf ,yum,还是 apt,它可以帮助你处理好所有细节。
开源、供应链与信任
此前有些国外用户对老冯表示过顾虑:“你是中国人,你搞的这个仓库看上去很好,但我们怎么知道没被你偷偷做手脚呢?” 面对这样的质疑,老冯也被噎过。说到底,这是典型的软件供应链信任问题。坦白讲,没有绝对的解决办法。 即便是 PGDG 官方仓库,比如其 YUM 仓库,也是凭借维护者 Devrim 的个人声誉来背书运转的。
老冯的回答是,构建这些二进制产物的所有工具,规范,文档,细节都是开源的,你自己也可以在本地轻松的自己构建出这些扩展来。 这样如果你不放心,完全可以用同样的工具箱在离线情况下直接构建自己的 RPM/DEB 仓库。
例如,你只需要使用下面这个简单的 Dockerfile,就可以立刻拉起标准构建环境,
然后当你想要构建扩展的时候,只需要使用 pig build pkg 命令,就可以了!
是的就是这么简单,比如你想要编译 timescaledb,这条命令会自动下载源代码,安装依赖,然后生成 deb 和 rpm 包:

目前 PGEXT.CLOUD 收录的所有扩展包,都是通过上述流程构建而成 —— 这意味着您也可以在任何支持的平台上,轻松从源代码构建出同样的扩展包!
目前的进展
PGEXT.CLOUD 其实并不算是 “新项目”,这套仓库基础设施已经运转五年了,包管理器和扩展目录有两年了。 这个新版本的网站目录倒确实是最近一个月新搞出来了的。所以从成熟度上来说,是已经“久经考验”,没啥问题的。
目前,这个仓库完全开源并免费向公众提供服务。托赛博佛祖 Cloudflare 慷慨免费套餐的福,最大的流量开销得以减免; 至于国内服务器托管,每月几百块的流量费,这点钱老冯还是掏的起的,哈哈。
老冯承诺会长期维护这个仓库。毕竟,这本来就是 Pigsty PostgreSQL 发行版自身需要的一部分,我也乐于将这份成果回馈社区。 我注意到,不少用户乃至业内同行其实只想方便地安装 PG 和各种扩展,所以我选择将 pig 工具和 PGEXT.CLOUD 仓库从 Pigsty 项目中抽离出来, 作为以 Apache 2.0 宽松许可证开源的独立项目服务大众。
有人问我,难道扩展不是 Pigsty 的一个核心价值点与壁垒吗?你就这么开源免费给别人白嫖打白工? 老冯的观点是 —— 顶级的企业与开发者就是应该通过构建互利共赢的生态,让所有参与者都能从中获益。
这一举措也已经初见成效。例如,业内同行 Omnigres 和 AutoBase 在他们的 PostgreSQL 发行版中引入了这个扩展仓库,不费吹灰之力就让他们的发行版与用户获得了 431 个 PG 扩展的强大能力。 再比如,一些扩展开发厂商(ParadeDB、TensorChord、MooncakeLab 等)也能够借助 Pigsty 仓库,轻松将自己的扩展作品分发给全球用户。
不仅如此,我们的仓库还收录并分发了多款不同风味的 PostgreSQL 内核分支 —— Supabase 的 OrioleDB、Percona 的 TDE 内核,瀚高的 IvorySQL、阿里云的 PolarDB、易景的 openHalo 等, 都可以通过这个仓库一键安装启用。PGEXT.CLOUD 不仅服务于扩展作者和使用者,同样助力各路 PG 厂商为用户创造价值。
放眼未来
目前在 PostgreSQL 扩展这条赛道上,除了老冯的 pig 项目可谓高歌猛进之外, 其他方案似乎反响平平:原本声势浩大的 Tembo Cloud 也跑去凑 AI 的热闹,弃坑不干(还坑了 PGXN 作者 David 一把); pgxman、pgxn 等也都一直都没啥声响和进展。
真正还能在容器化场景下提供扩展分发能力、与我们一较高下的,大概只有欧盟 StackGres(Alvaro 提供的 Kubernetes 方案)。 不过 StackGres 走的是 Cloud-Native 路线,而老冯专注的是 Linux-Native,本就是井水不犯河水,各取所需。
顺带一提,Pigsty 和 StackGres 还是 Supabase 官方 唯二两个支持三方开源自建 Supabase 的发行版,也是一个 Linux 原生,一个 K8S 方案。就是因为也只有我们两家把 Supabase 的核心 —— 扩展问题给解决好了。
众所周知,PostgreSQL 的成功离不开其极致的可扩展性和繁荣的扩展生态。 老冯真心希望通过 PGEXT.CLOUD 为这个生态添砖加瓦,树立起扩展分发的事实标准, 让扩展作者、用户以及 PG 厂商都能享受到更多增值红利,拥有更卓越的使用体验。
作为一个完全开源的项目,PGEXT.CLOUD 热忱欢迎来自各方的贡献!如果您发现还有哪些扩展遗漏未收录, 或者在使用过程中遇到任何问题,欢迎随时提出 Issue。作为扩展作者,如果您因缺少跨平台打包分发能力而烦恼,老冯也很乐意帮您解决这些难题; 作为 PG 产品厂商,我们更鼓励您直接采用 PGEXT.CLOUD 的仓库与工具,将 PostgreSQL 丰富的扩展生态无缝交付给用户。
写到这里,不禁有些感慨——从个人兴趣的小项目,到如今服务全球 PG 社区的一项基础设施,PGEXT.CLOUD 的成长离不开每一位开源同行的支持。 未来,老冯将继续保持初心,与大家携手推动 PostgreSQL 生态更上一层楼!让我们共同解锁 PG 生态的全部潜力,畅想更加精彩的数据库未来!

归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
12 - 冷门但稀缺的技能:打包构建
最近我的朋友,Omnigres 的创始人尤里跟我聊天,他说想要招一个 PostgreSQL 打包专家 —— 当然具体的岗位名字,他起了个 EEE —— Extension Ecosystem Engineer,也就是“扩展生态工程师”,倒是挺有意思。他发的这个 JD 是公开的,我就直接贴在下面了。
稀缺的技能:Linux 打包
我觉得他的这个 JD 有点儿过分,DevRel + SRE + DBA + Building Engineer + PostgreSQL 专精 六边形战士,简直是照着我写的,但老冯还真没见过其他有这种组合的人,所以我还是建议他老老实实找一个精通 Debian/EL 打包的构建工程师更实际一些…。但尽管如此,我认为难度还是挺大的,因为熟悉 “打包构建” 这个技能的人,咱都不能说用”稀缺“来形容了(更稀缺的应该是 DevRel)。
当然这里其实上下文语境,说的是 PostgreSQL 数据库内核/扩展在 Linux 操作系统上的构建打包。主要是 C 和 C++,还有一些 Rust,Java,Go 之类的扩展与工具。打包的产物主要是 RPM 和 DEB 包,以 APT / YUM 软件仓库的形式交付。老冯认为,这是一个相当不为人知的高价值稀缺技能。
什么时候意识到这一点?
老冯第一次意识到构建打包这个事是在 2017 年,那时候我去聊 Pivotal,面试官就问了我一嘴,你会打包吗,我们现在没有会这个的。我就嘀咕,什么包? RPM 包?嘿还真是。后来 Pivotal 出来的姚老板(YMatrix)也问过我这个事,你是不是打包构建比较熟悉,我们现在就特别缺这个,又让我加深了印象。
后来其实我也看过许多国内国外的数据库公司发布的软件,打包这一块确实惨不忍睹。比如之前的 Greenplum 是怎么交付给客户的呢?是一个 CentOS 7.9 RPM 包。啊对,这个软件它就提供一个 EL 7.9 RPM 包,您想要在 EL 8, EL9,或者 Ubuntu / Debian 或者其他 Linux 上运行?拜拜了您呐!
包括阿里云的 PolarDB for PG ,瀚高的 IvorySQL,本来也就是一两个 EL RPM 包的样子,在老冯的 Push 下总算是支持齐活主流 Linux 发行版了。MySQL 兼容的 OpenHalo 内核和 OrioleDB ,干脆就是我直接自己上替他们打包了。

构建打包的价值
打包这个技能很稀缺,但价值在哪里?其实你会发现,绝大多数终端用户 并不在乎你是不是开源,他们在乎的是有没有一个稳定可靠(最好免费)的二进制软件包可以下载。就比如说 Greenplum 闭源了,但现在还时不时的有朋友来管我要 Greenplum 的 RPM 包。姚老板的 YMatrix (GP7 闭源分支)虽说是闭源商业软件,但因为免费提供试用下载,大家也照样能用着,谁管你开不开源。
更鲜活的例子是最近 Kubesphere 社区断供 —— 源代码其实还是在那里的,但是你把二进制产物(镜像)给直接删掉了,这就影响到终端用户了 —— 你开不开源其实对用户毛影响都没有。真正会出现供应链卡脖子问题的,从来都不是软件的源代码,而是软件制成品。
构建打包让开源软件自主可控
开源专家 Tison在他的公众号文章《如何安心使用开源软件?》和 《开源软件有断供的风险吗?》其实深入聊过这个问题。结论就是:开源软件是没法断供的,但是开源制品是可以断供的 —— 想要安心使用开源软件,最重要的还是拥有一份本地的软件副本,或者建设自己的软件仓库。这里的核心就是打包构建。
就比如最近的 《PostgreSQL PGDG 仓库断供》这件事,全世界几乎所有镜像站都跟 PGDG 上游失去同步了,停留在五个月前的过时版本。目前全世界只有德国的 XTOM,俄罗斯的 YANDEX,和老冯在中国的 PIGSTY 提供手动更新的 PGDG 最新软件镜像。
当然,镜像站也只不过是同步一下人家做好的软件二进制制成品,退一万步讲,如果 PGDG 不是停止增量同步而是直接彻底锁死。那你要是想完全独立从零搭建起一个软件仓库出来,针对 RISC-V,MIPS ,ARM 等乱七八糟的国产架构分门别类构建,那么打包构建依然是绕不过去的一道门槛。
打包和打包不一样
当然有人会说,哎呀,都是开源软件,你可以自己从源代码编译呀?这话说的不假,使用现代语言编写的软件已经针对打包构建流程做了很多优化了。比如,用 Go 语言写的程序就非常容易构建打包,甚至还有 goreleaser 这样的神器,可以一键帮跨平台构建所有组合,生成 RPM / DEB 包,构建并推送 Docker 镜像然后自动创建 GitHub Release ,而你让 Vibe Coding 帮你实现这样的工作流可能都要不了半个小时。
但是,我们说的并不是这些,而是像 Debian,PostgreSQL 这样的巨无霸生态型项目(基本上基于 C / C++)。而且,构建打包 PostgreSQL 数据库,可不是几个 RPM 包就完事了。我这么说,现在我提供的10个发行版Linux发行版 x 5个PG大版本,再加上扩展和工具,总共有4万多个左右的 RPM/DEB 包。
打包构建并不是一件轻松的工作:要处理好各种依赖,glibc,icu,openssl,PostGIS 带着的一颗硕大无朋的依赖数。各种插件依赖的各种奇奇怪怪的系统库,不同操作系统发行版甚至是大版本上的版本冲突, cmake,make,ninja,cargo 各种构建工具的用法,诸如此类。
你为什么不用Docker?
Docker 似乎是来 “解决” 打包构建的一种捷径 —— 一次构建,到处运行 —— 才怪。我的意思是:用 Docker 你可以不用处理 Linux 操作系统大版本的组合因子(比如 el9, d12, u24 这种差异),但你依然要针对 PG 大版本,系统架构,以及几百个扩展和他们的多个版本进行构建。第二,如果你去看 Postgres Docker 镜像,就会发现其实它的 Dockerfile 里也还是用 apt install 去安装 PGDG 的 DEB 包的…。Linux 软件包是 Docker 镜像的上游,而不是相反。
第三,PG 的扩展是它区别于其他数据库的核心特色之一,而 Docker 容器镜像至今也没有办法优雅解决 PostgreSQL 扩展插件持久化的问题 —— 你不知道用户到底需要几百个扩展中的哪一个,然而全部装上又显得过于臃肿和愚蠢。Alvaro 在这一方面正在进行一些前沿探索,但老冯感觉距离成熟实践还有距离。
老冯怎么干起打包了?
老冯干打包这个事也就是从两年前,那时候我要提供在 Pigsty 里自建 Supabase 的能力,但是 Supabase 用到了十几个 PG 的扩展插件,这些扩展插件大部份都不在 PGDG 官方的二进制仓库里面。我问了问 PGDG YUM 仓库的维护者 Devrim,他说,Rust 写的扩展永远也进不了 PGDG 仓库,因为编译太慢了!所以老冯就只好自己上手,给这些扩展打好了 RPM 包。后来既然都打了 RPM 包,就干脆把 DEB 包也做了 —— 再后来,既然都已经支持了十几个 PG 扩展,那干嘛不把 PGDG 官方仓库不支持的两百多个 PG 扩展也打包交付了?
一步一步走到今天,老冯独立维护了一个 PostgreSQL 扩展仓库,里面包含了 9 种风味的 PG 内核,以及两百多款 PG 扩展(加上 PGDG 的总共 423 个可用扩展)。目前是 全世界 PG 生态收录最多可用扩展制品的仓库了。不谦虚的说,说起 PostgreSQL 打包构建,我和 Devrim(YUM 仓库),Christoph(APT 仓库),Álvaro(OCI 仓库),David Wheeler(PGXN) 算是这个赛道的顶级玩家了。
最直观的例子就是,Supabase 作为目前 AI 赛道的当红炸子鸡与数据库最大赢家,本应吸引大量厂商入局,但直到现在,有能力提供自建 Supabase 能力的开源 PostgreSQL 发行版,目前也只有老冯的 Pigsty (基于原生 Linux RPM/DEB),以及 Alvaro 的 StackGres(基于 OCI 镜像与 Kubernetes )

—— 因为我们都解决了这些 Supabase 专有扩展的构建打包分发问题。其实卡点就在这里,Supabase 即使把他的扩展源代码开源出来(后面还要换 OrioleDB 内核),又有几个人懂?又有几个用户有能力用起来?
说到底,单纯懂 EL / Debian Linux 打包的工程师其实还是有一些的,但是同时熟悉 PostgreSQL 生态,能为 PostgreSQL 几百个包在十几个系统发行版构建的人确实是凤毛麟角了。
懂打包的凤毛麟角
在现实实践中,老冯发现这个技能真的太稀缺了,就像尤里问我谁还懂这个,国内就甭说了,就算是全球,我知道的可能 ZoomboDB 那个作者(pgrx 作者)懂这个(被 ParadeDB 挖走了),别的我还真想不出来有谁能做好这个事情了。
比如说,PG 生态中,这么多扩展,能有有能力直接在发布的时候提供主流 Linux RPM / DEB 包的,我知道的就只有 ParadeDB 一家(pg_search),而他们会做这个事是因为他们发版太频繁了,我实在懒得替他们打包了,所以手把手教他们应该怎么打 RPM/DEB 包。另一个会自己打包的是 pgroonga,timescaledb,citus,但是怎么说呢,打的包和 PGDG 规范不统一,而且经常缺这个缺那个 —— 比如 citus 一直就缺 ARM 的包,Timescale 则缺几个特定的发行版,pgronnga 针对的是 Debian 自带的 PG 去打的包 —— 诸如此类。
再比如说国内的数据库厂商, 之前阿里云的 PolarDB for PG 和 IvorySQL 也就几个 EL RPM 包,后来我使劲儿 push 他们,总算是 Pigsty 支持的 10 个主流操作系统发行版现在都有包了。我也帮他们解决过几个低级打包错误。另外那个 MySQL 兼容的 OpenHalo,老冯干脆自己上了,替他们打好了 DEB/RPM 包。同理,Supabase 收购的 OrioleDB 看上去也没有这个能力,所以我也替他们做了 RPM / DEB ,在 Pigsty 中开箱即用。

小结
很多时候,价值源于非共识,打包构建就属于这种半瓶水外行看上去 “不就是编译封装一下”,但实际上相当稀缺的技能,脖子卡的嗷嗷叫的技能。
References


归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
13 - 从PG“断供”看软件供应链中的信任问题
这个月发生了一起沸沸扬扬的 “开源断供”事件—— KubeSphere 删除镜像跑路, 但其实还有另一件略隐蔽的 “卡脖子案例”,老冯在上个月提到过 —— 《卡脖子:PGDG切断镜像站同步通道》。 这次 “PostgreSQL 断供” 某种程度上扮演了试金石的角色,倒是很好的试出了各家数据库厂商和云厂商的成色。
老冯对此感到非常失望,停止将国内的云厂商和大学镜像站作为软件供应链上游,直接自建了 PGDG YUM/APT 仓库的国内最新同步镜像。
PGDG的“断供”
PostgreSQL 是数据库领域的祖师爷级开源项目,也是世界上最流行,最受喜爱,需求量最大的数据库。 绝大多数的用户都是通过 PGDG APT / YUM 仓库,来在 Linux 上安装 PostgreSQL 数据库的。 不幸的是,PGDG (全称:PostgreSQL 全球开发组)的 APT / YUM 软件制成品仓库在今年五月中旬对外关闭了 ftp 与 rsync 同步通道, 这导致了几乎全球的镜像站点都与上游仓库失去同步,存放的都是几个月前的旧版本软件包。
老冯在 7月7号的 《卡脖子:PGDG切断镜像站同步通道》一文中详细介绍过这个问题。 那时候老冯观察到德国的 XTOM 其实尝试手工按月手工更新的策略,其他基本上所有镜像站全军覆没,都停留在三四五月的状态。 昨天我重新统计了一下,发现俄罗斯的 YANDEX 也手工跟进了 APT 仓库,其他的镜像站依然是老样子。
| 供应商 | 区域 | 同步时间戳 | URL |
|---|---|---|---|
| 阿里云 | 中国 | 2025-03-31 | 同步时间戳 |
| 腾讯云 | 中国 | 2025-03-31 | 同步时间戳 |
| 火山云 | 中国 | 2025-03-10 | 同步时间戳 |
| 华为云 | 中国 | 2024-01-02 | 同步时间戳 |
| 清华 TUNA | 中国 | 2025-03-31 | 历史截图 |
| 浙江大学 | 中国 | 2025-03-31 | 同步时间戳 |
| 中科大 | 中国 | 直接下架 | 下架公告 |
| TrueNetwork | 俄罗斯 | 2025-01-31 | 同步时间戳 |
| JAIST | 日本 | 2025-03-31 | 同步时间戳 |
| DOTSRC | 丹麦 | 2025-03-31 | 同步时间戳 |
| MirrorService | 英国 | 2025-03-31 | 同步时间戳 |
| 普林斯顿大学 | 美国 | 2025-03-31 | 同步时间戳 |
| YANDEX | 俄罗斯 | 2025-08-13 | 镜像 |
| XTOM | 德国 | 2025-07-24 | 镜像 |
| PIGSTY | 中国 | 2025-08-14 | 仓库文档 |
镜像站的“断更”
比如,17.5 等5月更新版本修复了 CVE-2025-4207 GB18030 相关漏洞, 而今天刚刚发布的 17.6 系列版本 更是修复了 3 个 CVE 和 55 个 BUG。 如果你是镜像站的用户,那么就没法及时更新跟进打补丁了。更别提下个月即将发布的 PostgreSQL 18 新大版本了。 现在还属于问题早期阶段,也就落后两个 PG 小版本,但很快再过一个月就会落后一个大版本。 然后各种积累的漏洞补丁,安全修复国内用户全都用不上,产生的暴露风险会越来越大
从这个角度上来说,上游软件供应链停止对下游提供更新,本质上确实符合 “断供” 的定义。不过 PGDG “断供” 的理由也还算充分 —— 他们上 CDN 了嘛。
PGDG为何“断供”
PostgreSQL 邮件列表里,5月20日有韩国镜像站的维护者问过这个问题,之前用 rsync 同步 PGDG 官方仓库怎么突然断了?
Davaid Page 给出的解释是,ftp/rsync 从来就不是官方承诺提供的服务方式。 PGDG YUM/APT 仓库也就两台物理机,每天却有 10TB 的访问流量,很多都是“非法流量”, 带宽要受不了啦!所以他们就把这个仓库给托管到了 Fastly CDN 上。
他们的想法也很显然 —— 我都用了 CDN 了,那专业 CDN 的节点和体验,不比零星的镜像站好多了? 官方可以有能力绕过镜像站直接对全世界用户提供服务, 那还要啥镜像站?于是就把 FTP rsync 给关掉了,只能通过 HTTP 访问。 看上去确实也没毛病,虽然断了镜像站同步,但也提供替代解决方案了 —— 直接用官方 CDN 就好了,也算是合情合理。
—— 你可以选择不用任何镜像站,直接使用 PGDG 官方仓库(他们刚搬到 Fastly CDN上)。
中国被卡脖子了?
镜像同步中断,对于世界上绝大多数地区的用户来说,其实影响还相对较小,因为他们总是可以去用 PGDG 新的 CDN 。 但唯独对中国来说,这就等效于制成品断供了 —— 因为众所周知的原因,中国访问不了这些 CDN 节点!如果这些镜像站不更新,中国用户就没的用了!
当然,你要是自己翻墙用什么的还是可以用的。但是你显然不能指望人人都会这个,而且即使翻了速度也还是很慢的。 所以国内的镜像站对于国内用户使用 PostgreSQL 来说依然是至关重要。 (也别说 Docker ,DockerHub 也被墙了,而且绝大多数 Docker Postgres 镜像也是从 APT 仓库里安装的…)
从这个角度来说, 中国用户这还真是被卡了一把脖子 —— 虽然本质上属于搬起石头砸自己的脚 —— 人家只是把增量的同步给关掉了,然后你用不了人家提供的替代解决方案而已。 但这个事情已经是这个样子,重要的是在这种背景下如何解决用户的问题。谁来解决这个问题呢?
中国用户想要 YUM/APT 安装 PostgreSQL 一般只能通过国内的镜像站来安装,最知名的应该是阿里云和清华大学的Tuna镜像站,当然还有浙大/中科大的源。 不幸的是,这些镜像站无一例外全都进入 “长期不更新” / “停止维护” 的状态 —— 但你也没法怪他们,毕竟免费嘛。
供应链风险
开源专家 Tison在他的公众号文章《如何安心使用开源软件?》和 《开源软件有断供的风险吗?》深入解释过,开源软件(源代码)本身是没有所谓 “断供” 风险的 —— 开源协议授予的一系列基本权利是不可撤销的,在这个维度下 “开源断供”从未发生过。对断供的担忧往往是对开源软件过度期待带来的误解。
但是用户对开源的依赖总是发生在具体的软件供应链上,保障开源依赖的供应链安全是有成本的 —— 开源制成品,也就是二进制软件包(RPM/DEB/镜像),以及开源制成品的交付渠道 —— 软件仓库(APT/YUM/Registry)是存在断供风险的。
原因也很简单,这都是有成本的,谁来支付这个成本是一个大问题。 开源开发者愿意支付大头的研发成本,很多时候是因为这个事对他们来说是一种有趣的娱乐。 然而分发,打包,构建仓库,提供持续稳定的企业级服务与供给很大程度上是一种负担。 比如国内一个GB流量卖你8毛钱,那你 PGDG 一天10个TB流量,一天就是几千块钱,对吧。 所以你看能搞开源镜像站的基本上要么就是高校要么就是大型互联网厂商,第一自己也要用,第二加双筷子没啥流量成本。
反过来说,这些使用开源软件的用户像 PGDG 和开源软件镜像站付费了吗? 嘿,没有,所以老实说,无论是从法律上,道义上,还真没法苛责什么,因为这就是开源的 STYLE —— 没有质保 —— 毕竟人家也没收钱,提供源代码是本分,但开源协议可没有规定说要提供开源软件二进制制成品,开发者和开源软件镜像站没有义务去做这种慈善。
如何解决供应链风险?
那么商业服务可以解决这个问题吗?毕竟,这么多国产数据库都是基于 PG 换皮,套壳,魔改弄出来的子孙后代,结果上游老祖宗被 Ban 了,确实有些滑稽,就没有人出来搞个中国的镜像站吗? 嘿,可能还真没有 —— 大部份情况下,这些数据库厂商都是直接白嫖镜像站(阿里云,清华)仓库的,或者说,交付方式甚至都不是软件仓库,而是丢给你一个 EL7 RPM 包,根本没有能力维护软件仓库。
老冯自己独立维护了一个 PostgreSQL 扩展仓库,里面包含了 9 种风味的 PG 内核,以及两百多款 PG 扩展(加上 PGDG 的总共 437 个可用扩展)。目前是 全世界 PG 生态收录最多可用扩展制品的仓库了。 不谦虚的说,说起 PostgreSQL 打包构建,我和 Devrim(YUM 仓库),Christoph(APT 仓库),Álvaro(OCI 仓库),David Wheeler(PGXN) 是这个赛道的顶级玩家与原始供应者。
但虽然我会打包构建,维护仓库,但是,在安装交付 PG 原生内核的时候,我还是会选择使用 “PG官方” 的 PGDG APT / YUM 仓库,PIGSTY 自己的仓库作为扩展补充仓库, 因为 Devrim 和 Christoph 已经干的足够好了!我会去做和他们工作有差异互补的事情。所以对于老冯的 PostgreSQL 发行版 Pigsty 来说,PGDG 仓库是 PIGSTY 的供应链上游, 国内区域因为有墙,阿里云镜像站是老冯的间接上游。现在的问题是这个间接上游,包括阿里云,清华,浙大,各种云在内的所有镜像站,全都趴窝断更没得用了,怎么办呢?
老冯在发现这个问题的时候,第一时间就给阿里云和清华TUNA的邮件列表上报了这个问题,也跟德哥聊过说过。不幸的是,几十天过去了,依然毫无波澜,没有丝毫动静。 就是没人站出来解决这个问题。老冯对国内这些云厂商和互联网厂商真的非常失望。但你也没法说人家 —— 对吧,人家毕竟是免费给你用的,你能说什么呢?
我行我上
所以老冯也懒得再啰嗦,直接自己动手就上了。其实动手了我才知道,这才多大点事和工作量? —— 人家不给你开放 ftp rsync 同步,那你就用 apt-mirror 和 reposync 直接从 HTTP 通道去同步不就行了?老冯昨天用 Claude Code 花了两个小时,写了个同步流程,把 PGDG 的 YUM / APT 仓库给拉了下来, 丢到 Pigsty 的仓库里,然后测试了一遍,非常顺滑。我干完之后的感想就是 —— 就这?这么大点儿活,就给国内卡成这样?草台班子理论诚不欺我。
当然 PG 仓库总量大几百个 GB,如果全部弄下来就太大了,我就只要了 Linux x86 / aarch64 架构的包,同步了 Debian 11/12/13 ,Ubuntu 22/24 ,EL 7/8/9/10 这几个主要 Linux 操作系统发行版大版本下的 PG 13 - 17 的包,然后只保留最新的版本,这样总大小就只有几十个GB 了。 拉了两个小时,同步回来,丢到国内 CDN 上,然后目前在 pig 0.6.1 和 pigsty 3.6.1 中, 我已经把阿里云源换掉了,会在这两天发布,彻底摆脱躺平摆烂的中间商依赖,实现真正的自主可控。
目前这个仓库和 Pigsty 本身一样,都是开源免费的。直接使用 Pigsty 肯定是自建 PostgreSQL 服务的更佳选择,但你确实也完全可以直接使用这里的 APT / YUM 镜像仓库。 直接对公众用户开放会有不少流量成本,不过老冯应该还是兜得住的 —— 虽然开源的本质就是无质保,但好在老冯向客户们承诺长期持续维护这个镜像仓库,所以免费用户也可以搭搭便车。如果有人想要赞助(服务器,CDN,打钱),老冯也非常欢迎。
这让老冯回想起一些往事,两年前老冯想要把 PG 扩展搞进来,但是想要偷懒借力,我看到有个叫 Tembo 还有 pgxman 的公司尝试在做 PG 扩展包管理器, 我就等啊等啊等了几个月,等到最后发现他们纯粹是光吹牛不干活,老冯就不等直接自己上了,做了 pig 包管理器,pg 扩展目录和扩展仓库,现在成为了 PG 生态最大的扩展仓库。 就好比像 Omnigres 和 Autobase 这样的开源 PG 发行版/项目,也都使用 老冯维护的 Pigsty 扩展仓库,向他们的客户去交付。老冯的软件仓库也开始成为别人的供应链的上游了。
“开源” 确实并不要求你向用户提供可靠稳定的二进制制成品,但真正重要的不是开源,而是信任 。 开源只是构建信任一种形式,持续的投入,交付的承诺,专注的热情, 面对问题的担当。 想要成为值得信赖,受人尊敬的社区参与者,有许多东西比丢一份源代码到仓库要重要的多。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
14 - 卡脖子:PGDG切断镜像站同步通道
最近老冯在构建 Pigsty 离线包的时候发现,在本地测试的时候安装的 PostgreSQL 版本不太对,17.4 比最新的 17.5 落后了一个小版本。而且在 EL10 上测试的时候发现有几个仓库报错了。奇怪的是,在香港使用全球默认仓库没问题,一旦在本地使用中国的镜像站就报错。

仔细一看,发现国内的镜像站点都与 PostgreSQL 上游仓库失去同步了:清华大学开源软件镜像站(TUNA)最后一次成功同步是5月16号,而阿里云阿里云镜像站最后的同步时间戳是 2025 年 3-31。国外的镜像站,比如 mirrors.xtom.de 也出现了这种问题,最后一次同步是 6月20日,但也明显可以看出手动更新与脱离同步的痕迹。

我搜索了一下,发现了在 PostgreSQL 邮件列表里 5月20日已经有韩国镜像站的维护者问了这个问题了,镜像站的维护者问之前用 rsync 同步 PGDG 官方仓库怎么突然断了?
PostgreSQL 贡献者之一的 Dave Page 回复到因为有大量的非法流量涌入 —— 他们决定永久关闭了原来非正式的 FTP 服务器,不再提供 rsync 同步选项,只允许通过 HTTP 访问了。
PostgreSQL 作为世界上最流行的数据库软件,绝大多数用户都是通过 PGDG 官方仓库下载安装预制的二进制成品软件,而非从源码编译。而这个仓库就托管在两台物理机上 —— 根据 PostgreSQL Infra Team 的统计,大概每天有 六千六百万的请求(约每秒 750 次下载),每天约 10 TB 的数据传输。

而且这个决定就是在 PGConf.Dev 2025 最后一天进行的,他们还有个演讲,说本来有四台服务器,现在就剩两台了,前面套了个 CDN。 然后一看这个流量太大吃不住,咔嚓一下 rsync / ftp 一关,全世界的 PostgreSQL 下游仓库都断了。 老实说,老冯觉得这是一件很扯淡的事情 —— 你把这些镜像站都挡在外面,用户到时候直接涌入原始上游,那流量不是更大了么。

但老实说,你还真没法苛责他们什么,因为这就是开源的 STYLE —— 没有质保 —— 毕竟人家也没收钱,开发者没有义务去一直做慈善。 但从另一个角度来说 这还真是卡了一把全球用户的脖子 :比如 17.5 修复的 CVE 漏洞,如果是用镜像站的用户,可能就没法及时更新了。
老冯已经把这个问题反馈给了 阿里云镜像站和 清华TUNA 镜像站的维护者,看看最近能不能修复。比如用 HTTP 去拉取更新。如果短时间内没法解决,老冯准备自己也把 PGDG 的仓库给拉下来一部分,丢到 Cloudflare 上先做一个镜像站。

从供应链安全的角度来看,Fork 魔改一个 PG 内核确实没什么卵用。但维护一个自己控制的软件二进制制成品仓库对于运维自主可控确实有着关键意义。

老冯也一直在想要不自己在国内弄个镜像站点,毕竟都已经搞了一个 Pigsty APT/YUM 仓库,多放个 PG 也不是什么事儿。但其实阿里云和 TUNA 之前一直做的都不错,所以一直也都是用的这两家作为国内用户的默认配置。
至于长期来看,其实俺重新编译打包弄一个专门的 PostgreSQL 仓库也未尝不可,毕竟最近老冯也打包了好几种 PG 分支内核,还有 PG 生态中 PGDG 没有收录的 250 多个扩展。在构建 APT / YUM 仓库上已经是骨灰级打包侠了。不过,主要的问题还是维护太费时间,而且国内的流量费也太贵了。不过如果有金主赞助赞助不限流量的大带宽服务器,老冯也很乐意额外用爱发发电。
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
15 - Postgres Extension Day,咱们不见不散
一年一度的 PostgreSQL 开发者大会即将在五月于蒙特利尔举办。同上次第一届 PG Con.Dev 一样,这次也有一天的额外的专场活动 —— Postgres Extensions Day,关注 PG 扩展的开发,交付,发布等方方面面。目前议程刚刚排出来,总共安排了 14 个 Session。

当然这次,我就不当观众了,我的演讲是下午的首场 —— “The Missing Postgres Extension Repo and Package Manager”。即 “PG 生态中长久缺失的扩展仓库与包管理器”。 我会介绍 Pigsty 提供的扩展仓库,以及 pig 包管理器。并分享在构建,维护 PG 扩展时会遇到的挑战与问题,与全球开发者分享中国开发者与数据库厂商(个体户,哈哈)在这方面的工作、教训与经验。

PGEXT DAY 的举办日期是 2025.05.12 日,和 PG 开发者大会在相同的地点 —— 加拿大魁北克省蒙特利尔市,Plaza Centre-Ville。扩展峰会之后紧接着 12 - 16 号就是 PG 大会主会的日程了。

去年 PG 开发者大会在温哥华举办,参加之后感觉收获满满,可惜来自中国的参加者寥寥无几。不知道这一届怎么样,如果您也会去现场欢迎留言,我们可以在现场碰一碰,线下面基。
如果您对 PostgreSQL 感兴趣,可不要忘了在 https://pgext.day 上注册 —— 友情提示,虽然 PGEXT DAY 属于 PGCON Dev 的附属活动,但不同于主会场 500 加币的门票,参加 pgext.day 是不收钱的!所以如果来参加 PG 开发者大会,可不要忘了这个。
下面是 PG 扩展峰会的日程安排,期待在扩展峰会与读者朋友们相见!
扩展峰会的日程

1. 从 pl/v8 到 pl/<any>:迈向更容易的扩展开发
9:00 am → 25 min,Hannu Krosing
From pl/v8 to pl/: towards easier extension development
pg_tle 为开发者打开了一扇新大门,让任何人都能在无超级用户权限的前提下编写并部署安全的扩展。它还提供一些钩子,供受信任语言的函数使用,例如强制执行密码策略。 而 pl/<any> 则进一步允许使用任意语言来编写数据库函数,从而实现扩展。其主要途径是在 JavaScript 中编写 Language Handler,并利用任意可被转译到 JavaScript 的语言,成为 PostgreSQL 的嵌入式(或“pl/”)语言。
示例包括:
- pl/jsonschema:基于 AJV JSON Schema 校验库,将 JSON Schema 定义直接变为可运行的校验函数,性能有时远超使用 Rust + PGRX 封装的 pg_jsonchema。
- pl/wasm:能以标准 PostgreSQL 函数的方式运行编译后的 WebAssembly,计算密集型代码速度可接近原生代码的 2-3 倍。
- pl/codelength:示例性 Handler,把任何源代码变成一个返回原代码长度的函数。
未来还可在 pl/v8 基础上进一步拓展,例如:
- 编写自定义 FDW(类似 Python 里 Multicorn)
- 编写自定义逻辑解码插件
- 暴露更多钩子和跟踪点,以便在 JavaScript 中添加 Handler
- 让用户可直接构造计划树,甚至增加新的节点类型或监控探针
2. 将大版本升级封装成一个扩展
9:30 am → 25 min,Andrey Borodin
Upgrade as an extension
(暂无内容介绍,但这个标题看上去就很 Excited!)
3. 内联 Postgres 函数:现在与未来
10:00 am → 25 min,Paul Jungwirth
Inlining Postgres Functions, Now and Then
当 PostgreSQL 调用用户定义函数(或内置函数)时,可能会尝试进行内联,这为 SQL 开发者与扩展作者提供了新的可能性。本次分享将介绍 PostgreSQL 目前使用的两种内联方式(你现在就能用),以及一个正在开发中的补丁,旨在支持对大多数返回集函数进行内联。你的函数可用一个“计划树”自身替换,之后优化器会将它和查询中的其他部分融合在一起,这几乎就像写一个宏一样!
4. Postgres 点菜:自选扩展的动态容器镜像
10:30 am → 25 min,Alvaro Hernandez
Postgres à la carte: dynamic container images with your choice of extensions
在构建 Postgres 容器镜像时,通常需要捆绑所需扩展,但出于安全与体积考虑,不可能把所有数以百计的可用扩展一次性打包进去。 然而,不同用户需要的扩展组合又极其多样,如果为每一种可能组合都构建专属容器镜像,数量恐怕会超过宇宙中的原子数。
于是,“动态 OCI(容器)镜像”技术应运而生,可在实时、即时构建阶段,生成包含所需扩展的 Postgres 镜像。这些镜像可在 Kubernetes 等任何兼容 OCI 的环境中使用。
本次演讲将探讨动态容器镜像背后的理念与技术,以及如何应用它来为 Postgres 镜像加载任意扩展组合。演讲中会穿插大量演示!
5. Cppgres:少一个讨厌 C++ 的理由
11:00 am → 25 min,Yurii Rashkovskii
Cppgres: One less reason to hate C++
用 C 写 Postgres 扩展常常令人感觉繁琐、易错又重复度高。虽然很多开发者因为 C++ 的复杂性而对其敬而远之,但现代 C++ 拥有丰富特性,可让我们更轻松地编写可靠、易维护的 Postgres 扩展。
如果你还在考虑转投 Rust,不妨先看看 C++——只需沿用同样的编译器,也能享受到更多安全性与易用性。
本次分享将介绍 Cppgres:一个轻量级、仅含头文件的 C++20 库,能精简并强化 Postgres 扩展的安全性与可读性。借助概念、自动类型推导等现代 C++ 技巧,你能写出简洁、高效且可维护的扩展。让我们重新认识 C++,一起让 Postgres 扩展既安全又快乐!
6. 使用 MemoryContext 并调试 Postgres 中的内存泄漏
11:30 am → 25 min,Phil Eaton
Working with MemoryContexts and debugging memory leaks in Postgres
本次演讲将聚焦如何在实际场景中创建与切换 MemoryContext,并借助 Linux 的 eBPF 等工具来发现内存泄漏。内容基于生产环境中的真实案例,总结了在编写扩展并寻找 Bug 过程中的经验与实用技巧。
7. 作为控制平面的 Postgres:使用扩展卸载计算的挑战
12:00 pm → 25 min,Sweta Vooda
Postgres as a Control Plane: Challenges in Offloading Compute via Extensions
随着 Postgres 的角色从存储层扩展到控制平面,用于编排外部系统(例如向量搜索引擎)的扩展时,需要在性能、一致性与集成之间做好平衡。
本次分享将探讨如何设计 Postgres 扩展以卸载计算,并保持 SQL 简单性与事务保证。我们将结合 pgvector-remote 的实际经验,深入探讨缓冲、谓词下推、连接池及 VACUUM 等 Postgres 内部机制。
非常适合希望在 Postgres 中卸载计算,又想保留 SQL 简单性与性能的工程师。
8. 午餐
12:30 pm → 60 min
9. 缺失的 Postgres 扩展仓库与包管理器
1:30 pm → 25 min,Ruohang Feng
The Missing Postgres Extension Repo and Package Manager
哈哈,真的是我。
尽管 PostgreSQL 扩展功能强大又灵活,大多数用户还是希望“开箱即用”,而非自己编译与手动构建。为解决这一痛点,我整合了一个统一的仓库(pigsty.io/ext/list/),打包了 200+ 扩展,补足了官方 PGDG 仓库的缺口。这些 RPM/DEB 包支持 5 个 Linux 发行版、五个主流 PostgreSQL 版本以及 x86 与 ARM 架构,一站式覆盖。
本次分享将探讨如何构建这一仓库,包括跨发行版兼容、多架构支持、版本对齐等挑战,并分享经验教训及未来改进方向,让 PostgreSQL 扩展安装更轻松。
10. 如何自动在 PGXN 上发布你的扩展
2:00 pm → 25 min,David Wheeler
How to automatically release your extensions on PGXN
当前还没有一个所有 PostgreSQL 扩展的统一发布中心。PGXN 虽是目前最大的扩展源代码发布服务,但它仅收录了大约三分之一的公开扩展,且有些版本并不够新。
PGXN 致力于成为所有扩展版本的根注册中心,未来希望将所有发布信息同步给下游,以便自动化构建流程。要实现这一点,需要开发者主动将更新扩展上传至 PGXN,从而惠及整个 PostgreSQL 社区。
本次演讲将演示如何在 PGXN 上设置发布流程,以及通过 Git、JSON、GitHub workflows 等实现自动化,让你的扩展保持最新,一键发布到 PGXN。
11. 用 Java 扩展 PostgreSQL:克服 Java 与 C 应用交互的开发挑战
2:30 pm → 25 min,Cary Huang
Extending PostgreSQL with Java: Overcoming Development Challenges in Bridging Java and C Application
Java 和 C 两种语言设计理念与内存管理方式迥异。看似南辕北辙的两种语言,若掌握正确方法,依然可以配合得天衣无缝,一同扩展基于 C 的 PostgreSQL,并与 Java 应用或库联动。
本次演讲将分享 SynchDB 项目的开发历程,该项目通过在 PostgreSQL 端编写 C 扩展、并集成 Java 版 Debezium Embedded,引导来自 MySQL、SQL Server、Oracle 等多种源的数据变更流入 PostgreSQL。
我们将深入探讨在一个扩展内同时使用 C 与 Java 时面临的关键挑战与解决方案,包括:
- 基于 JNI 的跨语言调用
- 将 Debezium Embedded 嵌入 C 扩展的过程
- 内存管理与性能开销的应对
- 如何在架构层面整合 2 种语言组件
- 错误处理、监控及可维护性最佳实践
听众将了解如何增强 PostgreSQL 在逻辑复制方面的能力,并学到在单一扩展中融合 C 与 Java 的开发要领。
12. 重新思考 OLAP 架构:pg_mooncake v0.2 的历程
3:00 pm → 25 min,Cheng Chen
Rethinking OLAP Architecture: The Journey to pg_mooncake v0.2
在本次演讲中,我们将探讨 pg_mooncake v0.1 所存在的不足,以及在 v0.2 中所做的主要架构变更。我们还会分享在使用 Postgres 复制、后台工作进程及扩展形式的进程间通信(IPC)过程中所获得的经验教训。
13. Spat:劫持共享内存,在 PostgreSQL 中获得类 Redis 的使用体验
3:30 pm → 25 min,Florents Tselai
Spat: Hijacking Shared Memory for a Redis-Like Experience in PostgreSQL
传统数据库常把共享内存用于查询执行、缓存与事务管理等工作区,对用户不可见。但如果我们把它改造成可供用户直接使用的高性能数据结构和缓存又会怎样?
本次分享将介绍 PostgreSQL 向扩展开发者开放的共享内存 API(包括新的 DSM Registry),以及如何构建 Spat:一个把数据完全存储在共享内存、可在 PostgreSQL 内部提供类 Redis 体验的内存数据结构服务器。
Spat 提供类似键值存储的模式,支持字符串、列表、集合、哈希等结构,成为 PostgreSQL 内部轻量且高速的临时存储方案。 我们会探讨在这种超出传统范畴的共享内存用法中遇到的种种挑战与机遇,为有意将 PostgreSQL 扩展到新高度的开发者提供思路。
14. 使用 Citus 扩容 PostgreSQL:为现代应用而生的分布式数据
4:00 pm → 25 min,Mehmet Yilmaz
Scaling PostgreSQL with Citus: Distributed Data for Modern Applications
本次演讲将探讨 Citus 扩展如何将 PostgreSQL 演变为可横向扩展的分布式数据库。我们会深入介绍 Citus 的架构、作为扩展的部署方式,以及实际生产环境中的应用要点。
内容包括:
- Citus 如何将 PostgreSQL 扩展为支持分布式查询处理与数据分片
- 扩展打包、发布及在不同环境部署的最佳实践
- 在分布式 Postgres 集群的运维中,性能调优与安全机制的思考
- 成功落地的真实案例和经验教训
15. 扩展能力:新选项与愿望清单
4:30 pm → 25 min,Alastair Turner
Extensibility - new options and a wish list
当下是成为 PostgreSQL 扩展开发者的好时机——社区不断壮大,甚至出现了专门的扩展峰会活动。
同时,Postgres 也在持续开放更多可扩展领域。过去一年里,一些核心提交让 EXPLAIN、累计统计、COPY 等部分也具备可扩展性,但在存储等少数领域上,相关提案仍待推进。
本次分享将带你了解近期新的可扩展领域(附示例代码),并探讨在那些尚未突破的领域(尤其存储)上可能的改进与努力方向。
16. 晚餐
6:00 pm – 9:00 pm
Dinner
回顾 2024 年 PGCon.Dev
- Andreas Scherbaum PostgreSQL Development Conference 2024 - Review
- PgCon 2024 Developer Meeting
- Robert Haas: 2024.pgconf.dev and Growing the Community
- How engaging was PGConf.dev really?
- Cary Huang: PGConf.dev 2024:在温哥华塑造 PostgreSQL 的未来
- PGCon.Dev 扩展生态峰会小记 @ 温哥华
- PG大会2024开幕,温哥华饭搭子驴友团呢?
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
16 - 小猪骑大象:PG内核与扩展包管理神器
最近我在忙一个非常有趣的新项目,这两天总算弄完了。各位朋友们,给大家介绍一下这个有趣的小东西,PostgreSQL 与 Pigsty 中久久缺失的一个命令行工具,我称之为 “pig”。
那么 pig 是干什么的?简单来说,这是一个 PostgreSQL 的包管理器,也是 PostgreSQL 与 Pigsty 中久久缺失的一个命令行工具,它可以在主流 Linux 操作系统上提供跨发行版的丝滑无缝的 PostgreSQL 安装部署体验。而且还通过国内镜像解决了下载速度慢和部分仓库被墙的问题。

当然,安装 PG 这种事算不上有什么技术挑战,真正有难度的是 PostgreSQL 生态中的扩展插件。PostgreSQL 有着数据库世界中独一无二的繁荣扩展生态,提供各种强大而惊人的能力。而 pig 则能够在(Debian / Ubuntu / EL )三大 Linux 主流发行版(五个大版本 x AMD/ARM 两大架构)上,提供 340 个 PG 插件开箱即用的能力。

为什么插件对 PG 至关重要?请参阅《PostgreSQL正在吞噬数据库世界》
快速上手
pig 本身是一个 Go 编写的二进制程序,您可以直接从 Release 页面下载,或者使用 Pigsty 现成提供的 YUM / APT 仓库,使用操作系统的包管理器安装。
使用 pig 分两个步骤,首先,使用 repo 子命令添加上游仓库
然后,您就可以使用 ext 子命令搜索,查阅,安装,卸载,更新扩展了。是的,如果你就是安装个扩展,也就是一行命令这么简单。
你可以用命令行完成各种操作,文档里会详细介绍各种高级用法。此外,pig 还提供了一个 sty 子命令,用于安装 Pigsty 本身:
为什么需要包管理器?
那么在包管理器出现之前,用户想要安装 PostgreSQL 及其扩展,是怎么样的体验呢?当然你可以直接从源代码编译。PG 内核本身编译安装还是“很简单”的,几条命令就可以,不过 PG 生态的核心扩展 —— 地理空间事实标准 PostGIS 的编译安装基本上就立刻跳到地狱难度了。
尽管如此,编译安装对 绝大多数用户 来说基本属于早已失传的古代技能了。根据我对社区的观察,你能对用户做出的最大期待就是会用 yum/apt install,然后会照着文档敲为数不多的 Linux 命令。再高的工作假设就显得不切实际了。
PGDG官方仓库有什么问题?
尽管 PostgreSQL 官方提供了官方的 PGDG YUM / APT 仓库,但是这里依然有不少的问题:首先扩展数量只有一百个左右,其次,这里只有一半扩展是同时在 YUM / APT 仓库中提供的。最后,针对不同的 PG 大版本,芯片架构,操作系统发行版版本,经常性的会出现某个组合下的扩展缺失与错漏。

为了解决这个问题,我们提供了一个 PGDG 补充仓库,这有点类似于 EL Linux 上的 EPEL 源,补齐了大量缺失的扩展插件,并实现了 Debian / Ubuntu / EL 三大主流 Linux 的扩展功能集对齐,补齐了一块行业空白。我们的扩展仓库完全遵循 PGDG 的打包规范与命名惯例,使用相同的环境构建,确保与官方内核包无缝衔接对齐。

为什么用操作系统包管理器?
pig 被设计为原生使用 Linux 操作系统发行版现有的包管理器(yum / dnf / apt ),而非自己造一个全新的轮子。这是因为操作系统在解决依赖管理,升级降级这些问题上已经有了非常成熟且标准的实践了。并且毫无疑问最广大 PostgreSQL 用户群体早已接受并习惯于这一标准,因此我们认为打破这一标准的做法是远远弊大于利的。
因此,pig 仓库使用的软件包全部使用操作系统标准的 RPM / DEB 格式进行封装,确保它可以在主流的 Linux 发行版上丝滑安装与运行。Pigsty 在不同操作系统发行版上提供了一层统一的抽象,你只需要知道扩展名就可以安装,你不需要操心 PG 版本号,OS 大小版本,芯片架构,pig 会为你处理好所有细节。
使用 pig 工具扫描已安装的 PG 扩展
这个项目的价值在哪里?
抽象是软件能提供的核心价值。而 Pig 提供了一个相当优雅的抽象,解决好了 PostgreSQL 内核与扩展安装的问题。其实 Pigsty 在之前已经非常好的解决了这个问题 —— 你可以一键从裸操作系统上拉起装好所有 PG 扩展的插件,自带监控系统,高可用,PITR,还不要钱!
但我能理解,这样一个一揽子一条龙全家桶解决方案并非适用于所有用户 —— 特别是许多外国人更喜欢:每个工具做好一件事做到极致的方式。pig 其实是用 Go 重写了 Pigsty 的包管理部分。只不过之前 Pigsty 是用 Ansible Playbook 实现的,有个 Python 依赖。而 Pig 是一个干干净净没有依赖的 Go 二进制程序,开箱即用。
pig 除了可以一键安装 PG 扩展,当然也可以一键安装各种版本的 PG 内核。
这个项目的核心壁垒是什么?
pig 只是一个小工具,真正重要的是这个工具背后的 Pigsty 扩展仓库。这个仓库里维护了 140 个 PG 扩展,以及各种针对 PGDG 仓库补漏的构件。要构建这个扩展仓库,你需要有丰富的 PostgreSQL 经验与 Linux 操作系统经验,你需要同时熟悉 RHEL 与 Debian/Ubuntu 的打包方法,而老实说这是一项相当稀缺的技能。
我曾经跟 Pivotal (Greenplum)的团队聊天,老板说他们亟缺构建打包的专家。其实很容易就能看出来,他们发布的时候就一个可怜的 CentOS RPM 包。当然,说他们一句国内 PostgreSQL 综合实力第一的团队应该不为过,而这样的团队却依然没有懂这个的,这确实给我了一些启发。
现在这个仓库是什么状态
目前这个仓库里面提供了 150 个独特的 PG 扩展,包括二十来个 Rust 编写的强力扩展。独特的意思就是没有被收录到 PGDG 官方仓库里。PGDG 官方仓库有 100 个左右扩展,PIGSTY 仓库提供了 150 个,再加上 PG 自带的 70 个,总数 320 个,不过有些扩展只在 EL 有,有的只在 DEB 上有,所以总可用扩展数量目前是 340 个。
Provide 340 available extensions as RPM / DEB for PostgreSQL 13 - 17 in addition to the official PGDG repo.
Available on Linux: Debian 12 / Ubuntu 24.04 / 22.04 / EL8 / EL9 compatible OS distros, and
x86_64&ARM64architectures.
Entry / Filter All PGDG PIGSTY CONTRIB MISC MISS PG17 PG16 PG15 PG14 PG13 RPM Extension 334 114 147 69 4 6 303 330 333 321 303 DEB Extension 327 104 150 69 4 13 304 323 326 319 300
这 340 个扩展的质量很高,是已经经过我严格筛选后的结果。一些没鸡毛用的扩展,缺乏维护,年久失修的扩展,代码质量差的扩展,无法跨平台兼容的扩展,已经被我无情淘汰了大概二三十个了。我们有一个 PGEXT.CLOUD 扩展目录,详细收录了这 340 个扩展的元数据详情。在 pig 命令行工具里面也提供了检索与查阅详情的能力。

目前这个仓库托管在 Cloudflare 上,国内镜像放在腾讯云 CDN 上。每个月的下载量算上镜像大概 500 GB 左右,考虑到一个扩展也就几百KB,这个下载量还是相当可观的。
Pig 使用什么开源协议,如何考虑?
这个仓库本身的代码,以及 pig 工具没有使用 Pigsty 的严格 AGPLv3 协议,而是宽松的 Apache-2.0 开源许可证,这样做的目的也是为了让更多的用户与厂商参与进来。目前,这个仓库已经成为了两家友商 AutoBase (原 postgresql_cluster)和 Omnigres 默认使用的上游扩展仓库。
目前,我也在游说 CloudNativePG,Neon 和 Supabase 使用这个扩展仓库,我觉得问题不大,因为这属于互惠共赢的事情 —— 这些 PostgreSQL 发行版马上也可以宣称自己和 Pigsty 一样,340 个扩展开箱即用,哈哈。Omnigres 的创始人 Yurii 下下周来上海(PostgreSQL生态大会)跟我勾兑,我们准备搞个大新闻,尽可能把它做成 PG 世界的一个新事实标准。
为什么是你来做,而不是别人?
在年初,我提出了 可扩展性(Extensibility) 是 PostgreSQL 的核心属性,得到了社区的广泛认可与响应。我其实是期待生态里面有其他的人能够站出来,解决 PG 扩展分发的问题的。我曾经比较看好 Tembo 的愿景 —— 他们做了个 Trunk (宝箱),其实就是一个 PG 包管理器。我希望他们能做的足够好,这样我就不用操心扩展打包这些活了,直接拿过来就能用,整合到我的 PostgreSQL 发行版 Pigsty 里。

但是这半年观察下来,我发现包括 Trunk 也好,PGXMAN 也好,都是雷声大雨点小,不干实事的家伙,折腾来折腾去就那么些老扩展。而且愿景也比较扯蛋 :放着现有的 YUM / APT 实事标准不弄,一会弄个 OCI 镜像分发,一会弄个新 Catalog,唯独就是不解决用户的核心痛点 —— ”我他喵的现在就是想用这个扩展怎么办?“

五年前,我在 PostgreSQL 生态寻找足够好的监控系统,也遇到过这个问题。社区不给力怎么办,当然是我行我上了。所以我也懒得等了,直接自己上了。老实说这里有许多难题要解决,但技术问题都是可以解决的。在这半年里,我在这个领域积累了独一无二的经验 —— 一个人就维护了超过整个 PGDG 仓库,占总数近 60% 的扩展包。

谁还用包管理器,Docker不香吗?
我在 《把 PostgreSQL 放入 Docker 是一个好主意吗》这篇文章中深入聊过这个问题,其中特别提到过扩展的问题。总的来说,会遇到:扩展持久化的问题,安装扩展需要重新构建镜像,推送并重启的问题,难以同时组合使用扩展的问题。
一个简单的例子是插件与包管理,PostgreSQL提供了很多实用的插件,譬如PostGIS。假如想为数据库安装该插件,在裸机上只要
yum install然后create extension postgis两条命令就可以。但如果是在Docker里,按照Docker的实践原则,用户需要在镜像层次进行这个变更,否则下次容器重启时这个扩展就没了。因而需要修改Dockerfile,重新构建新镜像并推送到服务器上,最后 重启数据库容器,毫无疑问,要麻烦的多。包管理是操作系统发行版的核心问题。然而 Docker 搅乱了这一切,例如,许多 PostgreSQL 不再以 RPM/DEB 包的形式发布二进制,而是以加装扩展的 Postgres Docker 镜像分发。这就会立即产生一个显著的问题,如果我想同时使用两种,三种,或者PG生态的一百多种扩展,那么应该如何把这些散碎的镜像整合到一起呢?相比可靠的操作系统包管理,构建Docker镜像总是需要耗费更多时间与精力才能正常起效。
而且最重要的是你如果去看各种 PostgreSQL Docker 镜像的 Dockerfile 就会发现,它们几乎全都是使用操作系统的软件包来安装扩展的。说到底,这些活是省不了的。用 Docker 也改变不了这一点。
为什么叫 pig 这个名字?
我有一个开源的 PostgreSQL 发行版叫 Pigsty (猪圈),那么 pig 是作为 Pigsty 的管理命令行工具而存在的。猪圈里的动物是什么,自然是猪(pig)。当然,即使你不使用 Pigsty 这个 PG 发行版,你也可以独立使用 pig 这个命令行工具来安装,管理 PostgreSQL 与 扩展。

有一个比较有名项目叫 Apache Pig ,在 Hadoop 上提供 SQL-Like 的查询语言支持(Pig Latin),已经占用了 Pig 这个名字,我也思考了很久要不要使用其他名字比如 pk (pigsty keeper,猪圈管理员),或者就叫 pg 。但最后还是决定叫 pig,反正 Apache Pig 已经过气了,使用这套工具的环境和 Apache Hadoop 的用户也尿不到一个壶里去,基本没有命名冲突的风险,所以就这么办了。
下一步 pig 会如何发展?
如你所见,Pig 目前是作为 PostgreSQL 扩展管理器发布的,但它本质上是 Pigsty 的管控命令行工具。后续我会添加更多的功能,尽可能多地把 Pigsty 的一些功能移植进 pig 里来。
在另一个方面,既然我已经成为了构建打包编译大师,那么就应该把这个技能发挥到极致。目前 Pigsty 除了支持原生的 PG 内核之外,还支持 IvorySQL,PolarDB,Babelfish 这样的 PG 分叉内核(分别提供 Oracle 兼容,RAC,MSSQL 兼容能力),但有一个问题就是这些数据库内核目前是没有扩展支持的。比如,如果你想在兼容 Oracle 语法(使用 PolarDB-O 或 IvorySQL)的同时使用 pgvector,那你只能自己去编译。
PostgreSQL 生态的各种内核分叉 —— Kernels
我的计划是针对主流的 PG Fork,统一提供主流 Linux 系统上的 RPM/DEB 内核包 + 扩展包。让这些分叉也可以做到 340 个 PG 扩展开箱即用。目前我已经基本跑通了 OrieloDB 的流程,可能会在下个版本有一个草案与初步实现。
最后
希望 pig 这个工具,可以帮助你享受 PostgreSQL 和扩展插件的乐趣~。

归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。
17 - PostgreSQL神功大成!最全扩展仓库来了!
最近没怎么更新,因为在憋大招。最近功成出关,遂发此文为贺 —— 我做了一个收录PG生态所有能打的390个扩展的仓库,让 PostgreSQL 在成为数据库全能王的道路上又往前迈出了坚实的一步!
自从我在 《PostgreSQL正在吞噬数据库世界》 一文中指出 可扩展性 对于 PostgreSQL 的重要性以来,PG 社区对此进行了热烈的讨论,并且达成了共识。 最终体现在《PostgreSQL 17 发布注记!》中。
但真正重要的事情不是认识世界,而是改变世界。既然大家都已经认清了扩展很重要,那么我们应该做什么,怎么做,就成了真正关键的问题。
那么什么是 PostgreSQL 扩展最关键的问题?在我看来,扩展用得上用不上,是 PG 扩展生态的首要问题。
PG 扩展分发现状
大家知道 PG 生态有很多扩展插件,但这些扩展插件如何安装使用?这第一道门槛就成了许多用户的拦路虎。怎么解决这个问题? PGXN 说,用我的办法,我可以现场下载编译扩展; Tembo 说,我提前帮你打好 docker 镜像; StackGres 和 Omnigres 说,我们可以在线下载编译好的 So 文件; 八仙过海,各显神通。
大家都有很多好想法,唯独没仔细考虑绝大多数用户到底是如何安装扩展的。 作为前 DBA,我只能说什么现场编译,OCI镜像,下载so文件,在实战中都有些离谱了 —— 使用最广泛且最可靠的扩展安装方式,依然是用操作系统的包管理器安装签名二进制包。 而 yum / dnf / apt 在解决这个问题上已经做的足够好了!所以真的问题其实是,谁来把这几百个扩展插件打成开箱即用的软件包?
TIME: timescaledb timescaledb_toolkit timeseries periods temporal_tables emaj table_version pg_cron pg_later pg_background GIS: postgis postgis_topology postgis_raster postgis_sfcgal postgis_tiger_geocoder address_standardizer address_standardizer_data_us pgrouting pointcloud pointcloud_postgis h3 h3_postgis q3c ogr_fdw geoip pg_polyline pg_geohash mobilitydb earthdistance RAG: vector vectorscale vectorize pg_similarity smlar pg_summarize pg_tiktoken pgml pg4ml FTS: pg_search pg_bigm zhparser hunspell_cs_cz hunspell_de_de hunspell_en_us hunspell_fr hunspell_ne_np hunspell_nl_nl hunspell_nn_no hunspell_pt_pt hunspell_ru_ru hunspell_ru_ru_aot fuzzystrmatch pg_trgm OLAP: citus citus_columnar columnar pg_analytics pg_duckdb pg_mooncake duckdb_fdw pg_parquet pg_fkpart pg_partman plproxy pg_strom tablefunc FEAT: age hll rum pg_graphql pg_jsonschema jsquery pg_hint_plan hypopg index_advisor plan_filter imgsmlr pg_ivm pgmq pgq pg_cardano rdkit bloom LANG: pg_tle plv8 pllua hstore_pllua plluau hstore_plluau plprql pldbgapi plpgsql_check plprofiler plsh pljava plr pgtap faker dbt2 pltcl pltclu plperl bool_plperl hstore_plperl jsonb_plperl plperlu bool_plperlu jsonb_plperlu hstore_plperlu plpgsql plpython3u jsonb_plpython3u ltree_plpython3u hstore_plpython3u TYPE: prefix semver unit md5hash asn1oid roaringbitmap pgfaceting pg_sphere country currency pgmp numeral pg_rational uint uint128 ip4r uri pgemailaddr acl debversion pg_rrule timestamp9 chkpass isn seg cube ltree hstore citext xml2 FUNC: topn gzip zstd http pg_net pg_smtp_client pg_html5_email_address pgsql_tweaks pg_extra_time timeit count_distinct extra_window_functions first_last_agg tdigest aggs_for_vecs aggs_for_arrays arraymath quantile lower_quantile pg_idkit pg_uuidv7 permuteseq pg_hashids sequential_uuids pg_math random base36 base62 pg_base58 floatvec financial pgjwt pg_hashlib shacrypt cryptint pguecc pgpcre icu_ext pgqr envvar pg_protobuf url_encode refint autoinc insert_username moddatetime tsm_system_time dict_xsyn tsm_system_rows tcn uuid-ossp btree_gist btree_gin intarray intagg dict_int unaccent ADMIN: pg_repack pg_squeeze pg_dirtyread pgfincore pgdd ddlx prioritize pg_checksums pg_readonly safeupdate pg_permissions pgautofailover pg_catcheck pre_prepare pgcozy pg_orphaned pg_crash pg_cheat_funcs pg_savior table_log pg_fio pgpool_adm pgpool_recovery pgpool_regclass pgagent vacuumlo pg_prewarm oid2name lo basic_archive basebackup_to_shell old_snapshot adminpack amcheck pg_surgery STAT: pg_profile pg_show_plans pg_stat_kcache pg_stat_monitor pg_qualstats pg_store_plans pg_track_settings pg_wait_sampling system_stats meta pgnodemx pg_proctab pg_sqlog bgw_replstatus pgmeminfo toastinfo explain_ui pg_relusage pg_top pagevis powa pageinspect pgrowlocks sslinfo pg_buffercache pg_walinspect pg_freespacemap pg_visibility pgstattuple auto_explain pg_stat_statements SEC: passwordcheck_cracklib supautils pgsodium supabase_vault pg_session_jwt anon pg_tde pgsmcrypto pgaudit pgauditlogtofile pg_auth_mon credcheck pgcryptokey pg_jobmon logerrors login_hook set_user pg_snakeoil pgextwlist pg_auditor sslutils noset sepgsql auth_delay pgcrypto passwordcheck FDW: wrappers multicorn odbc_fdw jdbc_fdw mysql_fdw oracle_fdw tds_fdw db2_fdw sqlite_fdw pgbouncer_fdw mongo_fdw redis_fdw redis kafka_fdw hdfs_fdw firebird_fdw aws_s3 log_fdw dblink file_fdw postgres_fdw SIM: orafce pgtt session_variable pg_statement_rollback pg_dbms_metadata pg_dbms_lock pg_dbms_job babelfishpg_common babelfishpg_tsql babelfishpg_tds babelfishpg_money pgmemcache ETL: pglogical pglogical_origin pglogical_ticker pgl_ddl_deploy pg_failover_slots wal2json wal2mongo decoderbufs decoder_raw test_decoding mimeo repmgr pg_fact_loader pg_bulkload
PostgreSQL 的 PGDG 官方仓库中,提供了大约 100 个左右的扩展,但存在各种问题:有的扩展在 Debian/Ubuntu 的 APT 仓库里有,在 EL 系统的 YUM 仓库里没有; 有的扩展在 EL8 上有,EL9 没有;有的扩展在 Ubuntu 22 上有,在 24 上没有;有的扩展针对 PostgreSQL 12 - 15 提供,PG 16,17 不提供;有的扩展只有 x86_64 架构,没有 arm 架构;有时候碰上这种问题确实蛮让人头疼。
怎么办?我行我上!
作为一个 PostgreSQL 发行版维护者,我曾经寄希望于 PG 生态的其他人来解决这个问题。 每当我看见 PGDG 仓库有出现错漏缺失,我都会第一时间反馈给仓库维护者 Devrim 和 Cris 。
有的时候这种模式挺管用,比如去年当我发现 pgvector 这个强力向量数据库扩展还没有二进制软件包制成品时,我第一时间提给 Devrim , 将其放入 PGDG 仓库,然后 pgvector 遂成为 PG 生态中的向量数据库事实标准,进入到各家云厂商 RDS 中。
但有的时候,事情并不能总能如意。例如,Devrim 表示,他绝对不会接受任何 Rust 扩展插件进入 PGDG YUM 仓库。 但我确实有二十多个用 Rust 编写的 PostgreSQL 扩展需要分发(例如自建 Supabase 就需要 pg_graphql, pg_jsonschema, wrappers 三个 Rust 扩展),怎么办呢?
再比如说,最近 PG 生态非常火热的 DuckDB 缝合大赛,大家都在密集地更新跟进 DuckDB 系扩展 ,这些扩展插件我第一时间 打好了 RPM/DEB 包,但是如何分发呢?
思来想去,我决定还是我行我上,自己维护一个 PostgreSQL 扩展插件的 APT / YUM 仓库,分发 PG 扩展。
PG 扩展大全
在过去的半年中,我的工作重心放在 PG 扩展生态的整合上。而最近,这项工作终于达到了一个让我自己感到满意的里程碑。我建设了一个 PG Yum/APT 仓库,收录了 340 个可用 PG 扩展的元数据,以及二进制制成品。
| Entry / Filter | All | PGDG | PIGSTY | CONTRIB | MISC | MISS | PG17 | PG16 | PG15 | PG14 | PG13 | PG12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RPM Extension | 334 | 119 | 139 | 70 | 4 | 6 | 301 | 330 | 333 | 319 | 307 | 294 |
| DEB Extension | 326 | 104 | 143 | 70 | 5 | 14 | 302 | 322 | 325 | 316 | 303 | 293 |
| RPM Package | 251 | 107 | 138 | 1 | 4 | 1 | 220 | 247 | 250 | 239 | 229 | 216 |
| DEB Package | 241 | 90 | 142 | 1 | 5 | 1 | 218 | 237 | 240 | 234 | 223 | 213 |
以上是这个仓库的一些统计数字:总共有 340 个可用 Extension,去除 PG 自带的 70 个,总共 270 个第三方扩展插件。这 270 个扩展插件中,有小一半是 PGDG 官方仓库维护的(126个RPM扩展,102个DEB扩展),另外的大一半(131个RPM,143个DEB)都是由我维护,修复,编译,打包,测试,分发的。
每一个扩展,我都针对最新的 PostgreSQL 12 - 17 这六个生命周期大版本分别打包构建,针对 EL8,EL9,Ubuntu 22.04,Ubuntu 24.04,以及 Debian 12 这五个绝对主流 Linux 发行版构建。此外也对 EL7,Debian 11, Ubuntu 20.04 这些过保系统提供部分有限支持。
这个仓库还解决了扩展对齐的问题,例如,原本在 APT 和 YUM 仓库中的扩展,APT 有一小半几十个扩展 YUM 仓库没有,YUM 仓库有一小半 APT 仓库没有。我把两者独有的扩展都尽可能移植到另一个操作系统生态中,现在只有 7 个 APT 扩展在 YUM 仓库中缺失,16 个扩展在 APT 仓库缺失,只占总数的 6%。很多 PGDG 扩展版本缺失的问题,也在这里得到了一并修复。
我提供了一个完整的目录,列出了支持的扩展,并且对每一个扩展,都给出了详情,依赖安装说明与注意事项。
我想,用户吭哧吭哧抱怨扩展编译失败的问题,应该能在这里得到最终的解决。
当然题外话是广告时间,安装这些扩展,使用这个仓库的最简单的方式是什么?当然是开箱即用的 PostgreSQL 数据库发行版 —— Pigsty —— 但这并非必选项。 你依然可以用简单的一行 shell 在任何 EL/Debian/Ubuntu 系统上启用此仓库。
使用Pigsty一次性配置好并拉起用于自建Supabase的PostgreSQL集群,只要简单地声明要安装哪些扩展插件即可!
一键自建 Supabase 所需的 PostgreSQL 集群,请参考样例配置文件:conf/supabase.yml。
这个仓库里有什么?
在 Pigsty 的扩展仓库中,所有的扩展都已经被预先分为了十五类之一:TIME,GIS,RAG,FTS,OLAP,FEAT,LANG,TYPE,FUNC,ADMIN,STAT,SEC,FDW,SIM,ETL,如下所示。
请移步 pgext.cloud 查看完整详情。
一些感想与体会
PG 每个大版本都会引入一些变动,因此维护一百多个扩展插件并不是一件轻松的事情。特别是一些扩展的作者都好几年没动静了,那还真就只能自己上。我自己修复了十几个扩展插件,提供了最新的 PG 大版本支持。能联系上作者的,我也提交了一堆 PR 或者 Issue,推动解决。
在这个过程中,我和许多扩展作者都建立了联系。例如,我手把手帮助 ParadeDB 的老板与作者 解决了 RPM / DEB 包打包与分发的问题。我说动了 duckdb_fdw 的作者使用一个单独的 libduckdb,并发布了 v1.0.0 ,我给一些PG扩展的作者发邮件/Issue,国产机器学习框架 PG4ML 的作者也找到了我希望能够通过这个渠道进行分发。
再比如说,最近 PG 生态 OLAP 缝合 DuckDB 的竞赛如火如荼,但不管是ParadeDB 的 pg_analytics,国内个人开发者李红艳编写的 duckdb_fdw,CrunchyData 的 pg_parquet,MooncakeLab 的 pg_mooncake, Hydra 和 DuckDB 原厂 MotherDuck 亲自下场搞的 pg_duckdb ,都被我在第一时间编译打包收录整合其中,做到了 —— 你卷你的,反正我全都要。
言归正传,我希望这个仓库能设立起 PostgreSQL 扩展安装分发的标准,解决让人头大的分发难题。目前最让我感到高兴的进展是,流行的开源 PostgreSQL高可用集群搭建项目 postgresql_cluster 的作者 Vitaliy Kukharik 已经将这个仓库作为默认启用的仓库来安装 PostgreSQL 扩展。
目前这个仓库 (repo.pigsty.io) 托管在 Cloudflare 上,所以没有什么流量成本。国内有一个镜像站点 repo.pigsty.cc,方便墙内用户使用,每个有小几百块流量费,不是什么大问题。两个仓库加起来,过去一个月的下载流量大概 200GB ,考虑到扩展平均几十KB到几MB的大小,总下载量小几十万是有了。
因为赛博菩萨 Cloudflare不收流量费,所以总的来说,我觉得做一个永久免费的声明与承诺并不困难,所以 So be it。我承诺这个仓库将持续维护并永久免费。如果有国内开源软件站点的朋友愿意赞助或提供镜像服务,欢迎联系我。
我相信我的工作可以帮助到全球PG用户,并对 PostgreSQL 生态的繁荣贡献一份力量。我也希望我的工作可以帮到您,Enjoy PostgreSQL!
归档说明(2026-08-30): 本文原载 vonng.com。文中的软件包数量、截图与上下文以原始发表日期为准;当前行为请以 PIG 文档和实时扩展目录为准。











































