Neon 仓库的 Postgres 版本升级指南:从上游小版本合并到子模块与 CI 全流程
【免费下载链接】neonNeon: Serverless Postgres. We separated storage and compute to offer autoscaling, code-like database branching, and scale to zero.项目地址: https://gitcode.com/GitHub_Trending/ne/neon
Neon 是一个将存储与计算分离的 Serverless Postgres 项目,其计算节点基于 PostgreSQL 深度改造而成。为了保证既跟进上游 PostgreSQL 的 bug 修复与安全补丁,又维持 Neon 自身的扩展特性,仓库维护了一套严谨的 Postgres 小版本升级流程。本文基于 docs/updating-postgres.md 整理出从「合并上游 release tag」到「更新 vendor 子模块」「跑通 Neon 测试与 CI」的完整操作步骤,并辅以仓库中的 Makefile、测试用例与目录结构佐证,帮助读者完整掌握 Neon 中 Postgres 的升级机制与实操方法。
为什么 Neon 需要一套独立的 Postgres 升级流程
Neon 的核心思路是「存储与计算分离」,计算节点运行的是一个被深度定制的 PostgreSQL。仓库通过vendor/目录下的 Git 子模块引入多个 Postgres 大版本分支(当前支持 v14 ~ v17,见 Makefile 中的POSTGRES_VERSIONS = v17 v16 v15 v14),并在其上叠加了诸多 Neon 专属改动:
pgxn/下的neon、neon_rmgr、neon_walredo、neon_test_utils等扩展,承载了页面存储、WAL 重放、逻辑复制等计算侧逻辑;compute/patches/中的一系列补丁(如pg_cron.patch、pg_hint_plan_v17.patch、plv8_v3.2.3.patch等),对应生产环境部署的扩展定制。
因此,当上游 PostgreSQL 发布新的小版本(如 15.3 → 15.4)时,Neon 无法简单地原地替换二进制,而必须:
- 在维护的 Postgres 分支上合并上游 release tag;
- 解决冲突并跑通 Postgres 自身测试;
- 通过
vendor/子模块把新版本引入 Neon 仓库; - 用 Neon 的端到端测试验证整个系统仍然可用。
docs/updating-postgres.md就是这套流程的官方操作手册。
前置准备:两套仓库与两个 remote
升级流程会同时操作两个仓库:
- Neon Postgres 仓库(
neondatabase/postgres):存放被 Neon 修改过的 PostgreSQL 源码,通过vendor/子模块挂载进 Neon 仓库; - Neon 仓库(
neondatabase/neon):本仓库,包含计算节点、存储节点、测试框架等所有代码。
建议先克隆 Neon Postgres 仓库并添加 Postgres 上游 remote:
git clone git@github.com:neondatabase/postgres.git cd postgres git remote add upstream https://git.postgresql.org/git/postgresql.git随后基于要升级的稳定分支创建自己的工作分支。Neon 的稳定分支命名形如REL_15_STABLE_neon(在docs/updating-postgres.md中反复出现):
git checkout -b my-branch-15 REL_15_STABLE_neon说明:
my-branch-15只是示例分支名,实际使用时建议按版本与意图命名,例如upgrade-15-4。后续docs/tools.md中提到的 ccls 等开发工具配置也是以vendor/postgres-v15为示例目录,可见 Neon 对多版本子模块的管理方式是一致且可预期的。
第一步:合并上游 release tag
PostgreSQL 的上游 release tag 形如REL_X_Y,例如 15.4 对应REL_15_4。
git fetch upstream REL_15_4 git merge REL_15_4合并时注意:
- 如果存在非平凡的冲突,务必在 merge commit 的提交信息里写明冲突情况与处理方式,方便后续维护者回溯;
- 合并完成后,先在本仓库内验证 Postgres 自身未被破坏。
第二步:运行 Postgres 测试套件
文档建议用 make 或 meson 任一方式运行 Postgres 回归测试:
make check # OR meson test -C builddir从 Neon 仓库的构建体系看,这一步与 postgres.mk 中的postgres-check-%目标对应——它会先postgres-install-%编译安装对应版本的 Postgres,再执行$(MAKE) -C $(BUILD_DIR)/$* MAKELEVEL=0 check。也就是说,Neon 在 CI 与本地构建里都有等价的「先编译、再跑 Postgres 回归测试」链路。
第三步:推送 Postgres 分支到 Neon Postgres 仓库
测试通过后,先把包含 merge commit 的分支推到 Neon Postgres 仓库,供 Neon 子模块引用:
git push origin my-branch-15第四步:更新 Neon 仓库的 vendor 子模块
接下来回到 Neon 仓库(若未克隆则先克隆):
git clone git@github.com:neondatabase/neon.git然后创建新的 Neon 工作分支,做三件事:
- 修改
revisions.json文件,将其指向你 Postgres 分支的 HEAD; - 更新
vendor/下对应版本的子模块分支; - 运行 Neon 测试套件。
revisions.json位于vendor/revisions.json,其作用与格式可以在测试用例 test_runner/regress/test_postgres_version.py 中看到:它以pg_version(如v15)为键,记录期望的「Postgres 版本号 + 提交哈希」对。测试会解析postgres --version的输出(形如postgres (PostgreSQL) 15.6 (85d809c124a898847a97d66a211f7d5ef4f8e0cb)),并断言其与revisions.json完全一致——这就是为什么升级时必须同步更新revisions.json。
更新子模块的官方命令是:
git submodule set-branch --branch my-branch-15 vendor/postgres-v15 git submodule update --remote vendor/postgres-v15其中:
set-branch把子模块.gitmodules中的默认分支切到你刚推送的 Postgres 分支;update --remote从该分支拉取最新提交并更新工作区。
第五步:运行 Neon 测试套件
升级后的 Postgres 必须通过 Neon 自身的端到端测试。文档给出的命令是:
./scripts/poetry -k pg15这里-k pg15是 pytest 的表达式过滤语法(按关键字匹配用例),./scripts/poetry是仓库提供的 Poetry 包装脚本。从仓库现状看:
- scripts/pytest 的内容是
poetry run pytest "${@:1}",即通过 Poetry 管理的 Python 环境运行 pytest; - pytest.ini 指定了
testpaths = test_runner、默认排除remote_cluster标记用例,并设置了 300 秒超时等约束; - 测试框架位于 test_runner,其中 test_runner/regress/test_postgres_version.py 就是用来「守卫」版本一致性的回归用例。
因此升级 PR 必须至少让这些用例通过,确保 Postgres 版本号与 commit 均符合revisions.json的预期。
第六步:提交、开 PR 并等 CI 变绿
在 Neon 仓库中提交你的改动,创建 Pull Request,等待 CI 通过。
第七步:把正式分支推回 Neon Postgres 仓库
CI 通过后,把合并完成的 Postgres 分支推送到 Neon Postgres 仓库的稳定分支上,覆盖旧的REL_15_STABLE_neon:
git push origin my-branch-15:REL_15_STABLE_neon第八步:更新 Neon PR 指向正式分支
最后,把 Neon 仓库中子模块分支改回正式的REL_15_STABLE_neon,修正提交并强制推送:
git submodule set-branch --branch REL_15_STABLE_neon vendor/postgres-v15 git commit --amend --no-edit git push --force origin这一步的意义在于:PR 在合并前引用的是你的临时分支,合并后子模块应指向长期维护的REL_15_STABLE_neon,避免留下指向个人分支的悬空引用。之后在获得审批且 CI 完成后合并 PR,升级流程即告完成。
仓库内的版本一致性守卫机制
除了流程本身,Neon 仓库还内置了「版本一致性」的自动校验,防止升级遗漏:
- test_runner/regress/test_postgres_version.py 会读取
vendor/revisions.json,比对postgres --version的输出版本号与 commit; - Makefile 的
POSTGRES_VERSIONS = v17 v16 v15 v14声明了所有受支持的 Postgres 大版本,升级时需逐一评估; - Dockerfile 与 compute/compute-node.Dockerfile 在构建镜像时会
COPY vendor/postgres-v14 ... vendor/postgres-v17,因此子模块更新后,构建产物也会随之更新; - postgres.mk 在配置阶段会读取子模块的
git rev-parse HEAD作为--with-extra-version,也就是说最终二进制里会内嵌 Neon Postgres 分支的 commit,这正是postgres --version输出中哈希的来源。
综上,升级 Postgres 小版本在 Neon 中不是简单的「换 tag」,而是一套「Postgres 仓库合并 → 子模块更新 → revisions.json 同步 → 双测试套件验证 → 分支推回」的闭环流程。按 docs/updating-postgres.md 逐步执行,并借助上述源码级守卫机制,即可安全、可追溯地完成一次 Postgres 小版本升级。
【免费下载链接】neonNeon: Serverless Postgres. We separated storage and compute to offer autoscaling, code-like database branching, and scale to zero.项目地址: https://gitcode.com/GitHub_Trending/ne/neon
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考