PostgreSQL 补丁等在哪里?Commitfest 数据揭示的评审缺口

2026-09-15 23 预计阅读时间: 1 分钟
来源: postgr.es AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

补丁迟迟不能合入,问题一定出在最终提交环节吗?Jimmy Angelakos 与 Andreas Scherbaum 在 PGConf.dev 2026 分享的 Commitfest 分析,给出了一个值得开发者注意的答案:在他们观察的数据里,更明显的等待发生在评审之前,而不是补丁已经准备好、只差提交的时候。

这场分析覆盖 2014 年 12 月至 2026 年 4 月的 58 次 Commitfest、6,678 个补丁和 899 位作者。它不是给贡献者或 committer 打分,也不是对 PostgreSQL 开发流程作故障诊断,而是把可观察的数字摆出来,让社区讨论。

补丁入口扩大,合入工作仍然集中

2015 年,Commitfest 记录了来自 125 位作者的 418 个补丁;2025 年,这两个数字分别达到 272 位作者和 885 个补丁。贡献规模大约翻了一倍。

但分析期内,总共只有 38 位不同的 committer 出现在记录中,每年实际执行提交的人数中位数为 26.5。前五位 committer 完成了 55% 的提交,前十位完成了 74%。

这说明工作集中,但不能直接说明谁效率低。Committer 提供的是高度专业化的时间和判断;人数也不等于可用工时。不过,补丁入口持续扩大而合入侧人数没有同步增长,确实提出了一个容量问题:新增工作由哪个环节吸收?

已合入补丁从提交到合入的耗时,可以用三个数字描述:

指标 耗时
中位数 80 天
第 90 百分位 256 天
第 99 百分位 711 天

作者使用中位数和百分位,而不是只看平均值,是为了避免少数超长等待的补丁主导结果。还有一个重要边界:这些耗时只描述最终合入的补丁,不代表所有提交的补丁。

真正显眼的队列:还没有人认领评审

直觉上,瓶颈可能是 Ready for Committer:补丁已经审完,只等有权限的人合入。然而测量时,处于这个状态的 54 个补丁,其状态停留时间中位数只有 3 天,第 90 百分位为 30 天。

相比之下,331 个活跃补丁里,有 196 个没有登记 reviewer,占 59.2%。这组补丁的等待时间中位数为 54 天,第 90 百分位为 244 天,最长达到 892 天。

历史数据也呈现类似现象:处于 Needs review 的补丁中,72.1% 没有分配 reviewer;已经获得 reviewer 的补丁中,72% 只有一位。

因此,至少在 Commitfest 的可见范围内,评审认领比最终提交等待更值得优先检查。但“没有登记 reviewer”不能自动等同于“完全没有发生评审”:邮件列表上的讨论可能没有进入应用记录。

贡献者回访也值得关注。2015 年首次提交补丁的作者中,73% 后来再次提交;2024 年的对应比例为 37%。整个样本中,42.6% 的作者只提交过一个补丁。

这些数字不能直接证明等待导致了流失。不同年份的作者拥有不同长度的后续观察窗口,2025 和 2026 年尤其不适合过早判断。它们更适合作为进一步调查的线索,而不是因果结论。

可以这样实践:给自己的评审队列做一次体检

下面不是 Commitfest 官方接口,也不复现演讲的完整统计方法。它是一个最小实践:假设你能把项目的补丁队列整理成 CSV,用 Python 标准库检查无人认领的活跃补丁。

运行前,把示例行替换为自己的数据。submitted_at 使用 YYYY-MM-DD;多个 reviewer 用分号分隔;active1 表示仍在处理。示例计算的是“提交至快照日期的年龄”,不是准确的状态停留时间。要测量后者,需要状态变更历史。

cat > patches.csv <<'CSV'
id,submitted_at,status,reviewers,active
101,2026-01-10,Needs review,,1
102,2026-03-01,Needs review,alice,1
103,2026-03-20,Ready for Committer,bob;carol,1
104,2025-12-01,Committed,alice,0
CSV

cat > queue_metrics.py <<'PY'
import csv
import math
import sys
from datetime import date
from statistics import median

path = sys.argv[1]
snapshot = date.fromisoformat(sys.argv[2])

with open(path, newline='', encoding='utf-8') as f:
    rows = list(csv.DictReader(f))

active = [r for r in rows if r['active'].strip() == '1']
unassigned = [r for r in active if not r['reviewers'].strip()]
ages = sorted(
    (snapshot - date.fromisoformat(r['submitted_at'])).days
    for r in unassigned
)
if any(age < 0 for age in ages):
    raise SystemExit('Snapshot precedes a patch submission date')

print(f'Active patches: {len(active)}')
if active:
    print(f'Without reviewer: {len(unassigned) / len(active):.1%}')
if ages:
    p90 = ages[math.ceil(0.90 * len(ages)) - 1]
    print(f'Unassigned age median: {median(ages):g} days')
    print(f'Unassigned age P90: {p90} days (nearest rank)')
    print(f'Oldest unassigned: {max(ages)} days')
else:
    print('No active patches without a reviewer')
PY

python3 queue_metrics.py patches.csv 2026-04-01

这个脚本的价值不是生成一张漂亮报表,而是让团队回答三个具体问题:哪些补丁没有负责人?哪些等待已经足够久,需要主动联系作者?哪些条目应该明确结束,而不是继续滚动?

若要进一步分析,建议记录状态进入时间、reviewer 认领时间,以及补丁条目、邮件线程和提交 ID 之间的关联。否则,“没人评审”可能只是记录缺失,“等待十年”也可能混合了长期不活跃与真实处理时间。

把指标当作路标,不要当作判决书

这份分析最大的限制是覆盖范围。作者指出,2021—2026 年的 git commits 中,只有约 17% 出现在某次 Commitfest 中;约 80% 的补丁只存在于 pgsql-hackers 邮件列表。两者统计对象不同,不能简单拼成一个完整漏斗。

Commitfest 也没有提供提交 ID、邮件线程和条目之间的完整交叉引用。因此,这是一扇观察窗口,而不是 PostgreSQL 开发活动的全景。

演讲刻意没有把观察包装成修复方案。文章随后提出的温和建议,则包括让正式关闭更容易、让 reviewer 路由更明确,以及把分诊视为一项有名字的工作。这些方向可以在其他项目里小规模试验:

  • 明确分诊责任:指定轮值人员检查新补丁,而不是默认“总有人会看”。
  • 显式匹配评审者:按模块、经验和当前负载邀请 reviewer,避免只填一个名字却没有实际认领。
  • 给长期条目一个结论:明确关闭理由,并说明什么条件下可以重新提交。
  • 同时看速度与质量:等待缩短不应以草率评审、维护者过载或技术标准下降为代价。

PGConf.dev 的特点也呼应了这个问题:2026 年的会议安排了现场 Commitfest、社区答疑和 unconference,让开发者能直接参与工作,而不只是听报告。对希望参与 PostgreSQL 的人来说,贡献不只有写补丁这一条路;帮助补丁获得可执行的反馈,同样是在推进项目。


相关推荐