Neon 仓库 ext-src 目录指南:PostgreSQL 扩展的升级与回归测试框架

📅 发布时间:2026/9/12 6:17:58
Neon 仓库 ext-src 目录指南:PostgreSQL 扩展的升级与回归测试框架
Neon 仓库 ext-src 目录指南PostgreSQL 扩展的升级与回归测试框架【免费下载链接】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 仓库 docker-compose/ext-src/ 目录展开它承载了 Neon 用于测试 PostgreSQL 扩展的两大核心场景Compute 版本升级时扩展的兼容性升级测试以及以普通用户身份主要面向云实例运行的回归测试。读完本文你将掌握该目录的组织约定、test-upgrade.sh与regular-test.sh等脚本的运行机制、pg_regress --use-existing的典型用法以及如何在 Docker Compose 环境中执行整套测试流水线。一、目录定位与设计目标docker-compose/ext-src/在 Neon 仓库中扮演扩展测试弹药库的角色其中存放的是PostgreSQL 扩展的测试文件而非扩展源码本身主要服务于两个目的见 docker-compose/ext-src/README.md扩展升级测试验证扩展在不同 Compute 版本之间升级后的兼容性。Neon 的存储与计算分离架构允许同一个分支timeline在不同 Compute 版本上挂载因此扩展的二进制与 SQL 升级路径必须被充分验证。普通用户回归测试以普通非超级用户身份运行回归测试主要用于云实例场景确保扩展在受限权限下依然行为正确。值得强调的是从目录结构看大部分扩展子目录只包含.sh脚本与少量.patch/.sql文件例如 docker-compose/ext-src/hll-src/ 下仅有regular-test.sh与test-upgrade.sh两个脚本。真正的扩展源码来自neon-test-extensions镜像测试脚本在容器内与/ext-src目录下的源码配合执行。二、目录结构约定每个扩展目录遵循统一命名与内部结构见 docker-compose/ext-src/README.md#L7-L14extension-name-src/ # 例如 hll-src、pgvector-src ├── test-upgrade.sh # 升级场景测试脚本可选 ├── regular-test.sh # 普通用户回归测试脚本 ├── neon-test.sh # 备用测试脚本当 regular-test.sh 不存在时使用 └── 其它测试文件视扩展而定如 *.patch、*.sql目录命名为扩展名-src的形态内部脚本承担两种职责regular-test.sh删除旧库 → 创建新库 → 安装扩展 → 运行回归测试test-upgrade.sh在升级后的 Compute 上验证扩展功能通常由test_extensions_upgrade.sh调度若regular-test.sh缺失运行器会回退到neon-test.sh再退化为make installcheck见 docker-compose/ext-src/README.md#L88-L90 与 docker-compose/run-tests.sh#L74-L83。三、目录中的可用扩展清单README 完整列出了一共 24 个扩展目录覆盖类型丰富从数据分析到向量检索、从任务调度到图查询一应俱全目录扩展功能hll-srcHyperLogLog近似基数统计的定长数据结构hypopg-src创建假设索引不真实建索引即可查看执行计划ip4r-srcIPv4/IPv6 及子网数据类型pg_cron-src在 PostgreSQL 中运行周期任务pg_graphql-srcPostgreSQL 的 GraphQL 支持pg_hint_plan-src执行计划提示hintpg_ivm-src增量物化视图维护pg_jsonschema-srcJSON Schema 校验pg_repack-src低锁重组表pg_roaringbitmap-srcRoaring bitmap 实现pg_semver-src语义化版本数据类型pg_session_jwt-srcPostgreSQL 的 JWT 认证pg_tiktoken-srcOpenAI Tiktoken 分词器pg_uuidv7-srcUUIDv7 实现pgjwt-srcPostgreSQL 的 JWT 令牌pgrag-srcPostgreSQL 的检索增强生成RAGpgtap-srcPostgreSQL 单元测试框架pgvector-src向量相似度检索pgx_ulid-srcULID 数据类型plv8-srcJavaScript 存储过程语言postgresql-unit-srcPostgreSQL 的 SI 单位prefix-src字符串前缀匹配rag_bge_small_en_v15-src用于 RAG 的 BGE 嵌入模型rag_jina_reranker_v1_tiny_en-src用于 RAG 的 Jina 重排模型此外docker-compose/ext-src/README.md 目录下还有alter_db.sh这样的辅助脚本以及仓库中对应补丁集 compute/patches/如pg_cron.patch、pg_hint_plan_v16.patch、pgvector.patch、plv8_v3.1.10.patch等供构建 Compute 镜像时打补丁使用。值得注意docker_compose_test.sh的SKIP列表中出现了rag_jina_reranker_v1_tiny_en-src、rag_bge_small_en_v15-src与pg_jsonschema-src见 docker-compose/docker_compose_test.sh#L110说明这些 RAG 相关扩展默认不参与 Docker 环境的回归测试。四、升级测试test_extensions_upgrade.sh的工作流4.1 前置条件与环境变量test_extensions_upgrade.sh 开头即校验三个必填环境变量第 10-15 行OLD_COMPUTE_TAG # 旧版本 Compute 镜像 tag NEW_COMPUTE_TAG # 新版本 Compute 镜像 tag TEST_EXTENSIONS_TAG # neon-test-extensions 镜像 tag同时通过PG_VERSION${PG_VERSION:-16}指定 PostgreSQL 大版本默认 16并导出PG_TEST_VERSION。该脚本只支持 v16与 docker_compose_test.sh 顶部注释一致Currently supports only v16。4.2 被测扩展清单脚本内置一个 JSON 数组EXTENSIONS以extnameSQL 中的扩展名与extdir本目录下的子目录名成对列出被测对象第 69-87 行共 17 项[ {extname: plv8, extdir: plv8-src}, {extname: vector, extdir: pgvector-src}, {extname: unit, extdir: postgresql-unit-src}, {extname: hypopg, extdir: hypopg-src}, {extname: rum, extdir: rum-src}, {extname: ip4r, extdir: ip4r-src}, {extname: prefix, extdir: prefix-src}, {extname: hll, extdir: hll-src}, {extname: pg_cron, extdir: pg_cron-src}, {extname: pg_uuidv7, extdir: pg_uuidv7-src}, {extname: roaringbitmap, extdir: pg_roaringbitmap-src}, {extname: semver, extdir: pg_semver-src}, {extname: pg_ivm, extdir: pg_ivm-src}, {extname: pgjwt, extdir: pgjwt-src}, {extname: pgtap, extdir: pgtap-src}, {extname: pg_repack, extdir: pg_repack-src}, {extname: h3, extdir: h3-pg-src} ]可见extname与目录名并不总是一一对应例如扩展名vector对应目录pgvector-src扩展名h3对应目录h3-pg-src这正是清单中要同时维护两个字段的原因。4.3 四阶段执行流程test_extensions_upgrade.sh将整个过程拆为四个阶段阶段 A在新版 Compute 上建库装扩展并记录版本以NEW_COMPUTE_TAG启动test-extensionsprofile 的 Compose 服务等待compute_is_ready服务日志中出现 accepting connectionswait_for_ready函数最多等 300 秒在contrib_regression库中用CREATE EXTENSION IF NOT EXISTS ... CASCADE批量安装全部扩展create_extensions函数通过pg_extension系统表查询各扩展当前版本号new_vers。阶段 B切到旧版 Compute创建每个扩展的独立 timeline用OLD_COMPUTE_TAG重建计算节点读取主 timelineSHOW neon.timeline_id并以它作为祖先调用 Pageserver HTTP API 创建子 timelinecreate_timeline函数第 38-51 行curl -sbf -X POST \ -H Content-Type: application/json \ -d {\new_timeline_id\: \...\, \pg_version\: ${PG_VERSION}, \ancestor_timeline_id\: \...\} \ http://127.0.0.1:9898/v1/tenant/${tenant_id}/timeline/restart_compute用指定 tag 与 timeline 重建 compute并用SHOW neon.timeline_id校验 timeline 一致check_timeline。阶段 C在旧版上安装扩展对每个待测扩展在旧版 Compute 对应的 timeline 上执行CREATE EXTENSION ext CASCADE模拟用户数据已存在于旧版本的状态。阶段 D升级到新版 Compute 并跑回归用NEW_COMPUTE_TAG在同一 timeline 上重启 compute —— 这一步真正触发了 Neon 的升级路径旧版本中创建的扩展对象现在由新版本 Compute 接管执行该扩展目录下的test-upgrade.sh失败时输出regression.diffs并退出依次执行ALTER EXTENSION ext UPDATE完成 SQL 脚本升级再用\dx ext展示升级后的版本号。该流程对应 README 中描述的创建一个装有旧版扩展的数据库 → 为每个扩展建 timeline → 切到新版测试升级 → 验证升级后功能四步见 docker-compose/ext-src/README.md#L50-L55。4.4 升级测试脚本示例各扩展的test-upgrade.sh内容高度一致核心是调用 PostgreSQL 自带的pg_regresshll-src/test-upgrade.sh#!/bin/sh set -ex cd $(dirname ${0}) PG_REGRESS$(dirname $(pg_config --pgxs))/../test/regress/pg_regress ${PG_REGRESS} --use-existing --inputdir./ --bindir/usr/local/pgsql/bin \ --dbnamecontrib_regression \ add_agg agg_oob auto_sparse card_op cast_shape copy_binary \ cumulative_add_cardinality_correction cumulative_add_comprehensive_promotion \ cumulative_add_sparse_edge cumulative_add_sparse_random cumulative_add_sparse_step \ cumulative_union_comprehensive cumulative_union_explicit_explicit \ cumulative_union_explicit_promotion cumulative_union_probabilistic_probabilistic \ cumulative_union_sparse_full_representation cumulative_union_sparse_promotion \ cumulative_union_sparse_sparse \ disable_hashagg equal explicit_thresh hash hash_any meta_func \ murmur_bigint murmur_bytea nosparse notequal scalar_oob \ storedproc transaction typmod typmod_insert union_op其中--use-existing是关键扩展已在阶段 C 安装pg_regress不再执行建库/装扩展的 SQL而是直接对既有数据库跑测试用例这与 README 中创建数据库后使用--use-existing绕过 pg_regress 权限限制的说明完全对应。pgs_repack-src/test-upgrade.sh 则用--inputdir./regress指向独立的回归用例目录并执行repack-setup repack-run error-on-invalid-idx no-error-on-invalid-idx after-schema repack-check nosuper get_order_by trigger等用例。pg_cron-src/test-upgrade.sh 展示了打补丁的用法#!/bin/sh set -ex cd $(dirname ${0}) patch -p1 test-upgrade.patch PG_REGRESS$(dirname $(pg_config --pgxs))/../test/regress/pg_regress ${PG_REGRESS} --use-existing --inputdir./ --bindir/usr/local/pgsql/bin \ --dbnamecontrib_regression pg_cron-test它先用 test-upgrade.patch 修改测试脚本——从 diff 可以看出补丁删除了测试用例中创建扩展 v1.0 → 升级到 v1.4 → 测试二进制兼容性 → 缓存失效测试 → 清理等步骤因为这些步骤在升级测试中由test_extensions_upgrade.sh的编排逻辑CREATE EXTENSION→ 重启新版本 →ALTER EXTENSION UPDATE统一完成pg_regress只需验证升级后功能是否正常。五、普通用户回归测试regular-test.sh模式对于以普通用户身份运行的回归测试每个扩展目录中的regular-test.sh遵循删库 → 建库 → 装扩展 → 跑回归的固定套路见 docker-compose/ext-src/README.md#L59-L66。以 pgvector-src/regular-test.sh 为例#!/bin/sh set -ex cd $(dirname ${0}) dropdb --if-exist contrib_regression createdb contrib_regression psql -d contrib_regression -c CREATE EXTENSION vector PG_REGRESS$(dirname $(pg_config --pgxs))/../test/regress/pg_regress ${PG_REGRESS} --inputdir./ --bindir/usr/local/pgsql/bin --inputdirtest \ --use-existing --dbnamecontrib_regression \ bit btree cast copy halfvec hnsw_bit hnsw_halfvec hnsw_sparsevec hnsw_vector \ ivfflat_bit ivfflat_halfvec ivfflat_vector sparsevec vector_type这段脚本同时演示了pgvector的多种索引/类型测试面halfvec、sparsevec、hnsw_*、ivfflat_*而--use-existing意味着扩展安装CREATE EXTENSION vector由脚本手动完成而不是交给pg_regress的installcheck流程。5.1 为什么必须--use-existingREADME 中专门解释了这个设计pg_regress默认会尝试为数据库设置lc_messages而普通用户无权修改该 GUC因此脚本先手动createdb再通过--use-existing复用既有数据库。docker_compose_test.sh中以-U cloud_admin连接、并由run-tests.sh的-r参数REGULAR_USERtrue驱动的测试链路正是围绕这一约束展开的见 docker-compose/run-tests.sh#L30-L38 与 第 74-77 行。5.2 数据库级环境对齐部分扩展对时区/日期格式敏感。仓库在 docker-compose/ext-src/alter_db.sh 中集中处理#!/bin/bash # We need these settings to get the expected output results. # We cannot use the environment variables e.g. PGTZ due to # https://github.com/neondatabase/neon/issues/1287 export DATABASE${1:-contrib_regression} psql -c ALTER DATABASE ${DATABASE} SET neon.allow_unstable_extensionson \ -c ALTER DATABASE ${DATABASE} SET DateStylePostgres,MDY \ -c ALTER DATABASE ${DATABASE} SET TimeZoneAmerica/Los_Angelesneon.allow_unstable_extensionsonNeon 对不稳定扩展的开关unstable_extensions.c是 Neon 计算节点中管控该行为的实现plv8等扩展依赖它才能正常安装DateStylePostgres,MDY与TimeZoneAmerica/Los_Angeles将数据库环境对齐到回归测试期望输出的固定时区避免regression.diffs因时区差异产生误报。plv8-src/regular-test.sh 会source ../alter_db.sh后运行并从make -n installcheck的输出中动态提取回归用例清单剔除startup_perms、find_function_perms、guc等对普通用户不可用的用例。六、CI 与编排入口README 指出两条主要工作流Cloud Extensions Test云项目上的扩展测试与Force Test Upgrading of Extension扩展升级强制测试它们由两个 shell 脚本驱动见 docker-compose/ext-src/README.md#L68-L79。6.1docker_compose_test.shDocker Compose 环境下的扩展回归docker_compose_test.sh 的功能更广——它会为TEST_VERSION_ONLY默认14 15 16 17指定的每个 PostgreSQL 大版本构建 Compute 镜像、启动全部服务、执行SELECT 1冒烟测试并在 v16 上进入扩展测试分支通过COMPOSE_PROFILEStest-extensions启用neon-test-extensions服务对应 docker-compose.yml#L198-L210 中profiles: [test-extensions]的neon-test-extensions容器它挂载/ext-src测试资源并依赖compute1用docker compose cp把 PostGIS、pg_hint_plan、file_fdw 等测试所需的 data/regress 文件复制进容器在容器内打上 compute/patches/contrib_pg16.patch或contrib_pg17.patch等补丁通过SKIP排除不适用的扩展timescaledb-src,rdkit-src,pg_jsonschema-src,...通过RUN_FIRSThll-src,postgis-src,pgtap-src让耗时长的测试优先并行执行调用容器内/run-tests.sh /ext-src跑扩展测试再调用/run-tests.sh /postgres/contrib跑 PostgreSQL contrib 测试失败时收集各目录的regression.diffs/regression.out输出后退出。支持PARALLEL_COMPUTES并行脚本会用yq基于 docker-compose.yml 生成docker-compose-parallel.yml复制出多台 compute并设置RUN_PARALLELtrue让各 compute 自行生成 tenant/timeline。6.2run-tests.sh目录级的测试运行器docker-compose/run-tests.sh 是容器内按目录遍历的通用运行器-r参数切换为普通用户模式REGULAR_USERtrue此时优先执行regular-test.sh依次尝试regular-test.sh→neon-test.sh→make installcheck与 README 的添加新扩展规则一致PARALLEL_COMPUTES 1时用 GNUparallel把各扩展分发到不同 computePGHOSTcompute{%}并支持RUN_FIRST与SKIP变量失败时统一 dump 各失败目录的regression.diffs。6.3 升级测试的完整编排test_extensions_upgrade.sh是升级测试的唯一入口其完整调用序列为NEW 版 compute 建库装全部扩展 → 记录各扩展版本 → OLD 版 compute 启动读取主 timeline → 为每个扩展创建子 timelinePageserver API → OLD 版 compute 上 CREATE EXTENSION → 切到 NEW 版 compute同 timeline→ 跑 test-upgrade.sh → ALTER EXTENSION UPDATE → \dx 校验版本FORCE_ALL_UPGRADE_TESTStrue时会对清单中全部扩展跑升级否则仅对new_vers与旧版版本号不一致的扩展执行升级测试第 106-111 行。七、如何新增一个扩展测试README 的Adding New Extensions一节给出了明确的接入步骤见 docker-compose/ext-src/README.md#L83-L99在docker-compose/ext-src/下创建extension-name-src/目录至少提供regular-test.sh普通用户回归测试脚本若不存在regular-test.sh系统会查找neon-test.sh两者都不存在时运行器退化为make installcheck对应 docker-compose/run-tests.sh#L79-L83 的实现test-upgrade.sh仅在需要测试升级场景时提供如需纳入升级测试还需在 test_extensions_upgrade.sh#L69-L87 的EXTENSIONSJSON 数组中补充{extname: ..., extdir: ...}条目。打补丁的约定docker-compose/ext-src/README.md#L94-L99将.patch文件放入扩展目录在合适的脚本test-upgrade.sh、neon-test.sh、regular-test.sh或Makefile中执行patch -p1 *.patch补丁会在测试过程中被应用。典型例子是 pg_cron-src/test-upgrade.patch它删除用例中重复的创建/升级/清理扩展步骤避免与test_extensions_upgrade.sh的外部编排冲突。八、与仓库其它部分的协同docker-compose/ext-src/并非孤立存在它与仓库其它模块形成完整测试闭环Compute 补丁集compute/patches/ 中的pg_cron.patch、pgvector.patch、plv8_v3.1.10.patch、pg_hint_plan_v16.patch等用于构建 Compute 镜像时对扩展源码打补丁docker_compose_test.sh还会在容器内应用contrib_pg16.patch/contrib_pg17.patch以适配 contrib 测试。Compute 镜像编排docker-compose/docker-compose.yml 定义了compute1、compute_is_ready、neon-test-extensions等服务其中neon-test-extensions通过 profiletest-extensions按需启用其镜像 tag 由TEST_EXTENSIONS_TAG控制。Neon 扩展机制测试中大量使用的neon.allow_unstable_extensionsGUC 对应计算节点内 pgxn/neon/unstable_extensions.c 的实现——Neon 通过不稳定扩展清单来管理那些可能随版本变化的扩展例如plv8这正是升级测试要重点覆盖的对象。升级测试的依托timeline 机制是 Neon 代码分支branching的核心能力相关设计与实现可参考 docs/rfcs/017-timeline-data-management.mdtest_extensions_upgrade.sh通过 Pageserver 的/v1/tenant/{tenant_id}/timeline/API 为每个扩展创建独立 timeline从而并行、隔离地验证升级路径。九、小结docker-compose/ext-src/是 Neon 扩展质量保障体系的关键一环它以目录 约定脚本的轻量方式把 24 个 PostgreSQL 扩展的升级兼容性验证与普通用户回归测试标准化。理解regular-test.sh、test-upgrade.sh、run-tests.sh、docker_compose_test.sh、test_extensions_upgrade.sh这五类脚本的分工与协作你就能在本地 Docker Compose 环境中复现 Neon 的扩展 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考