七月 6, 2026
扩展 Postgres 的高并发处理能力,绝不能仅靠简单粗暴地“堆硬件”。每一个数据库连接都会带来隐藏的系统开销,包括 Linux 操作系统的内存与 CPU 损耗,以及 Postgres 内部的 MVCC(多版本并发控制)和锁机制限制。为了应对高性能负载,我们需要停止盲目猜测,深入理解这些底层限制并对系统进行精准调优。
目录

Postgres 的多进程架构及其影响
- 架构特点:Postgres 在 1990 年代选择了多进程隔离架构以换取极高的稳定性。这种架构非常安全,但缺点是会产生较高的 CPU 和内存开销,并且依赖 Linux 的共享内存机制(如
tmpfs)进行进程间通信。 - 未来演进方向:社区正在讨论向基于线程的架构或混合架构(类似 Oracle)演进。但线程间共享堆内存的机制要求开发者在处理数据覆盖时必须格外谨慎。
核心调优方向与对比分析

1. 内存管理:大页(Huge Pages)是必选项
-
核心结论:必须使用大页(Huge Pages)来映射共享缓冲区(Shared Buffers)。
-
页表开销对比(以 8GB 缓冲区,1000 个活跃连接为例):
-
❌ 标准 4KB 页:每 1GB 缓冲区需要多达 2MB 的页表(PTE)。在上述场景下,系统页表理论上会膨胀至惊人的 16GB,造成极大的内存浪费。
-
✅ 2MB 大页:每 1GB 缓冲区仅需 4KB 的页中间目录(PMD)。同等场景下,页表仅占用区区 32MB,差异巨大。
-
避坑指南:务必禁用 Linux 内核的透明大页(Transparent Huge Pages, THP)功能,它会导致 Postgres 出现严重的性能问题。
2. CPU 调度:Linux 调度器的演变红利
- 旧版完全公平调度器 (CFS):追求绝对的平均主义,但这对于数据库中极其短暂、爆发式的事务(短查询)往往“不公平”,容易拖慢平均性能。
- 新版调度器 (EEVDF):Linux 内核 6.6+(如 Debian 13, RHEL 10)引入了“最早合格虚拟截止时间优先”(EEVDF)调度器。
- 优势:新调度器能优先处理低延迟、爆发式的连接。这意味着,仅仅是升级 Linux 系统版本,即便不修改任何 Postgres 配置,就能直接获得性能和延迟的改善。
3. NUMA 架构的配置策略
现代多核服务器多采用 NUMA(非一致性内存访问)架构,跨节点访问存在延迟惩罚。
- 实测结论:对于常规的 Postgres 负载,NUMA 跨节点的延迟惩罚在实际测试中影响并不显著。
- 策略建议:
- 内存分配:建议使用
interleave(交错/轮询)NUMA 策略,让进程和内存在各个节点间均匀分布,避免单节点瓶颈。 - 节点绑定(Pinning):将 Postgres 绑定到特定 NUMA 节点的做法,主要适用于工作负载隔离(例如在一台大型物理机上运行多个独立的数据库实例时)。
系统容量规划指南(核心指标清单)
1. 活跃连接数配置方法(按每 CPU 核心计算)
评估连接数上限时,应基于“活跃连接”而非空闲连接:
- 常规事务型负载(配备现代 SSD 并开启大页):每个 CPU 核心约 4 个活跃连接。
- 高频/极小型事务负载:每个 CPU 核心最高可达 6 到 8 个活跃连接。
- 分析型负载(OLAP):每个 CPU 核心 1 个连接。若启用并行查询(Parallel Workers),需为每个 worker 预留独立的核心。
- 注:若使用老旧硬件或未开启大页,建议降低上述吞吐量预期。
2. 内存使用评估与 work_mem 的陷阱
- 拒绝虚假内存:通过
top命令看到的连接内存往往因共享缓冲区而严重失真。应通过内核的smaps接口剔除共享映射(如/dev/zero (deleted)),才能得出真实的单连接内存占用。 work_mem的“乘法效应”:- 在一次简单的查询中,
work_mem并非只被分配一次,可能会被调用多次(如 2 次甚至 2.2 次)。 - 内存驻留问题:由于 Linux 堆内存“只能向上增长、向高处释放”的特性,即使 Postgres 认为底层内存块已释放,查询末尾产生的小对象仍可能导致堆内存无法完全归还给操作系统,形成内存驻留假象。这在设置了较小
work_mem时尤为明显。
Postgres 内部两大瓶颈提示
- MVCC 快照扩展性:在 Postgres 14 版本中得到了大幅优化,吞吐量更加稳定。但在极高并发连接下,它仍然是一个显著的性能瓶颈。
- 锁定对象数量限制:在 Postgres 17 及更早版本中,每个会话最多只允许 16 个对象使用本地“快速路径”进行锁定。超出此数量将强制访问中央共享锁表,从而引发轻量级锁(LWLock)的剧烈峰值。Postgres 18 针对此机制进行了重大改进,建议在需要处理大量锁对象的场景下尽快评估升级。