PostgreSQL 社区的开发门槛不低,尤其是查询优化器、执行器、测试体系这些核心区域。Floor Drees 这篇记录的重点不是一次普通聚会,而是一个内部培养项目的阶段性进展:一批被认为有 PostgreSQL 开发潜力的同事第三次线下会面,集中讨论开发路径、已提交补丁,以及接下来如何继续把贡献推向社区。
Developer U 的价值:把“会用数据库”推进到“能改数据库”
很多工程师熟悉 PostgreSQL 的 SQL、索引、扩展和运维参数,但真正进入 PostgreSQL 内核开发时,会立刻遇到几道墙:
- 代码库历史长,模块边界靠经验和文档共同理解。
- 补丁不仅要能跑,还要符合社区 review 习惯。
- Planner 相关改动尤其敏感,因为一个局部估算变化可能影响大量查询计划。
- 测试不是“补几个单元测试”那么简单,还要考虑回归测试、平台差异和计划稳定性。
这个项目的意义就在这里:它把贡献者培养从“自己摸索邮件列表和源码”变成了更有节奏的训练。线下会面则提供了高带宽讨论环境,适合拆解补丁、讲清设计意图、同步 review 状态。
Planner 补丁为什么适合作为训练场
标题里提到的 plan(ner) patches 很有意思。Planner 是 PostgreSQL 里最能体现系统工程味道的部分之一:它要基于统计信息、代价模型、约束、连接顺序、索引可用性等因素生成执行计划。
对新贡献者来说,Planner 补丁有几个训练价值:
- 能迫使你阅读真实查询如何被解析、重写、规划和执行。
- 改动通常需要清楚说明“为什么这个计划更合理”。
- 容易暴露测试设计能力:你要构造能稳定触发行为差异的 SQL。
- 社区 review 会要求你解释边界条件,而不只是展示 benchmark 数字。
但它也有风险。Planner 补丁不适合用“看起来更快”来判断成败。一个优化可能让某类查询变快,却让另一些查询选错路径。真正可合并的补丁需要说明影响范围,最好有可复现的测试和明确的退路。
可以这样实践:搭一个最小 PostgreSQL 补丁验证环境
下面的流程不是原文中的具体步骤,而是开发者可以用来练习 PostgreSQL 补丁的最小工作流。它适合用来复现一个 Planner 行为、跑回归测试,或者准备给社区提交的 patch。
运行前需要本机有 C 编译工具链、git、bison、flex、readline、zlib 等依赖。不同系统包名略有差异。
git clone https://github.com/postgres/postgres.git
cd postgres
# 使用独立安装目录,避免污染系统 PostgreSQL
./configure --prefix="$PWD/inst" --enable-debug --enable-cassert CFLAGS="-O0 -g3"
make -j"$(nproc)"
make install
# 初始化一个测试实例
./inst/bin/initdb -D ./data
./inst/bin/pg_ctl -D ./data -l ./server.log start
# 确认版本和连接正常
./inst/bin/psql -d postgres -c "select version();"
准备一个小查询,用来观察 Planner 输出:
./inst/bin/psql -d postgres <<'SQL'
DROP TABLE IF EXISTS demo_orders;
CREATE TABLE demo_orders (
id bigserial PRIMARY KEY,
customer_id int NOT NULL,
status text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now()
);
INSERT INTO demo_orders (customer_id, status, created_at)
SELECT
(random() * 1000)::int,
CASE WHEN random() < 0.9 THEN 'paid' ELSE 'refunded' END,
now() - (random() * interval '90 days')
FROM generate_series(1, 100000);
CREATE INDEX demo_orders_status_created_idx
ON demo_orders (status, created_at);
ANALYZE demo_orders;
EXPLAIN (ANALYZE, BUFFERS)
SELECT *
FROM demo_orders
WHERE status = 'refunded'
AND created_at > now() - interval '7 days';
SQL
如果你正在修改 Planner 相关代码,可以在改动后跑一个聚焦测试:
# 重新编译并安装
make -j"$(nproc)" && make install
# 跑核心回归测试,时间会比单个 SQL 长
make check
# 查看当前改动,生成补丁草稿
git diff > planner-experiment.patch
一个实用习惯是把“补丁想改变什么计划”写成 SQL 文件保存下来,例如:
-- file: repro/planner_case.sql
EXPLAIN (COSTS, VERBOSE)
SELECT *
FROM demo_orders
WHERE status = 'refunded'
AND created_at > now() - interval '7 days';
然后每次改动后固定运行:
./inst/bin/psql -d postgres -f repro/planner_case.sql
这类脚本不能替代正式回归测试,但能帮助你在开发中快速发现计划变化是否符合预期。
补丁之外,更重要的是 review 语言
这次会面摘要提到讨论主题、已提交补丁和下一步计划。对 PostgreSQL 这类社区项目来说,“提交补丁”只是中间状态。真正决定贡献质量的,是补丁能否被其他维护者理解、验证和维护。
准备 Planner 补丁时,可以用下面这个清单自查:
- 这个改动解决的是错误计划、缺失优化,还是代码结构问题?
- 有没有一个最小 SQL 能稳定展示差异?
- 是否依赖特定数据分布?统计信息变化后行为是否仍合理?
EXPLAIN前后差异能否说明问题,而不是只给出结论?- 新测试是否会因为成本数字、行数估算或平台差异变得脆弱?
- 补丁是否足够小,方便 reviewer 聚焦讨论?
对新贡献者来说,这种训练比“多写几行 C”更关键。PostgreSQL 的贡献过程重视公开讨论和渐进式共识。一个补丁能被接受,往往是因为作者把问题边界、实现取舍和测试证据讲清楚了。
采用建议:把培养计划变成可重复的工程机制
这类 Developer U 项目最值得借鉴的地方,是它没有把开源贡献完全交给个人热情。它通过固定人群、周期性会面、补丁实践和后续计划,把学习路径压实了。
如果团队也想培养数据库内核、编译器、运行时或基础设施方向的贡献者,可以从小处开始:选一个真实模块,安排阅读源码、复现 issue、写最小补丁、内部 review、再进入上游社区。不要一开始就追求大功能。能把一个小 patch 解释清楚、测清楚、改到可 review,已经是非常扎实的进步。
边界也要讲明白:Planner 和内核级补丁周期长,review 不可控,短期产出可能不像业务功能那样可预测。适合它的指标不是“本月合并几个 PR”,而是“多少人能独立构造复现、读懂 review、维护补丁版本”。这正是从使用者走向贡献者的关键台阶。