四月 22, 2026
摘要:大页 (Huge Pages) 的使用可以让 PostgreSQL 进程的内存页表更小,以及花费在内存管理上的 CPU 时间更少,从而提高性能。
目录
介绍
在 PostgreSQL 中,启用大页 (Huge Pages) 是一个非常有效的性能优化手段,尤其是在处理大规模数据和高并发负载时。
简单来说,Linux 默认的内存页大小通常是 4KB。当你为 PostgreSQL 分配了几十 GB 的 shared_buffers 时,操作系统需要管理数百万个页面,这会导致 CPU 在维护“页表”(Page Table)上花费大量时间。而大页(通常为 2MB)能显著减轻这种负担。
什么时候应该考虑启用大页?
你可以根据以下几个关键指标来决定:
1. shared_buffers 超过 1GB
这是最直观的判断标准。
- 如果你的
shared_buffers设置很小(比如几百 MB),4KB 的默认页完全够用,启用大页带来的提升微乎其微。 - 一旦
shared_buffers达到 2 ~ 8 GB 或更高,页表本身就会变得非常庞大。启用大页可以减少 TLB(转换后备缓冲区)的未命中率,显著提升 CPU 效率。
2. 系统内存总量较大
在拥有 64GB、128GB 甚至更多内存的服务器上,页表项会消耗大量的物理内存。通过使用大页,可以节省出几百 MB 甚至 GB 级别的内存空间供程序实际使用。
3. 内核态 CPU 开销高但 iowait 低
如果你通过 top 或 htop 观察到 CPU 的 %sys 占比很高,且数据库并没有频繁的系统调用,那很可能是 CPU 在忙着查找页表映射(TLB Miss)。
4. 高并发连接场景
PostgreSQL 的每个后端进程都需要映射 shared_buffers。如果连接数很多(例如几百个进程),每个进程都要维护一套庞大的页表映射。大页能大幅降低这种重复开销。
启用大页的收益与风险
| 维度 | 启用后的变化 |
|---|---|
| 性能提升 | 通常能带来 3% 到 10% 的整体性能提升,高负载下更明显。 |
| 内存占用 | 减少页表本身占用的内存。 |
| 稳定性 | 大页是“预分配”并锁定在内存中的,不会被交换到 Swap,保证了核心缓存的响应速度。 |
| 潜在风险 | 内存不可回收:大页一旦分配,即便 PostgreSQL 关闭,这部分内存也会被锁定,除非手动释放。 |
如何配置?
第一步:检查 PostgreSQL 的需求
你可以通过以下命令启动一个测试,看看 PostgreSQL 建议分配多少个大页:
运行时计算参数 shared_memory_size_in_huge_pages 会报告所需的大页数量。可以在启动服务器前用如下postgres命令查看:
$ postgres -D $PGDATA -C shared_memory_size_in_huge_pages
1091
第二步:操作系统层面配置 (Linux)
你需要计算所需的大页数量并写入系统配置。例如,需要分配 1091 个 2MB 的大页(共 2.1 GB):
$ sysctl -w vm.nr_hugepages=1091
并在 /etc/sysctl.conf 中持久化该设置。添加:
vm.nr_hugepages=1091
立即应用配置生效:
$ sysctl -p
第三步:结果验证
启动 PostgreSQL 服务,并验证是否成功启用大页。
执行下面命令,检查系统大页状态:
$ grep Huge /proc/meminfo
检查设置是否成功:
HugePages_Rsvd > 0(表示大页已被预留)HugePages_Free减少对应数值
如下:
$ grep Huge /proc/meminfo
AnonHugePages: 14336 kB
ShmemHugePages: 0 kB
FileHugePages: 0 kB
HugePages_Total: 1091
HugePages_Free: 1025
HugePages_Rsvd: 1025
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 2234368 kB
则说明 PostgreSQL 已成功使用大页。
查询大页的状态 huge_pages_status:
show huge_pages_status;
huge_pages_status
-------------------
on
(1 row)
结果为 “on”,确认配置生效。