HugePage 与 PostgreSQL 容器 core dump 完整解析
·
一、HugePage 是什么
- Linux 内核提供的内存管理特性,将物理页大小从默认 4 KiB 提升到 2 MiB(x86_64)或 1 GiB(大页 HugePage)。
- 优点:减少 TLB miss、降低页表内存、提升顺序扫描性能。
- 接口:内核参数
vm.nr_hugepages = N控制预留多少大页;进程通过mmap(MAP_HUGETLB)或shmget(SHM_HUGETLB)申请。
二、vm.nr_hugepages = 0 的含义
- 0 表示系统不预留任何 HugePage,等同于关闭该特性。
- 运行时设置立即生效,重启后需写进
/etc/sysctl.d/*.conf才能持久化。 - 设置后已分配的大页会被内核逐步回收(无进程使用时)。
三、PostgreSQL 何时会用到 HugePage
- 代码路径:
shmget(SHM_HUGETLB, size)申请共享内存段(shared_buffers)。 - 成功条件:
vm.nr_hugepages > 0且空闲页足够;- 进程
rlimit(RLIMIT_MEMLOCK)≥ 申请大小; - 挂载点
/dev/hugetlbfs存在且可写(可选)。
- 若任一条件不满足,PostgreSQL 会回退到普通 4 KiB 页,不影响功能;但 Patroni 容器场景下常因“半吊子”配置而触发 SIGBUS。
四、为什么在统信 UOS + 容器里出现 Bus error (core dumped)
| 层级 | 默认情况 | 结果 |
|---|---|---|
| 节点 | vm.nr_hugepages = 512 |
内核预留 1 GiB 大页 |
| 容器 | ulimit -l = 64 kiB |
无法锁定任何大页 |
| 运行时 | /dev/shm = 64 MiB |
共享内存越界 |
| 文件系统 | XFS + prjquota | mmap 对齐失败 |
触发链:
initdb → mmap(HUGETLB, shared_buffers=128MB) → 内核分配大页 → 容器 memlock 不足 → 页表项建立失败 → CPU 访问非法物理地址 → SIGBUS → Bus error (core dumped)。
五、解决办法
- 直接关闭 HugePage(最简单,数据库收益有限)
echo 0 | sudo tee /proc/sys/vm/nr_hugepages # 持久 echo "vm.nr_hugepages = 0" | sudo tee /etc/sysctl.d/99-uos-hugepage.conf sysctl -p /etc/sysctl.d/99-uos-hugepage.conf
更多推荐
所有评论(0)