必须用Oracle官方脚本hugepages_settings.sh在数据库已启动状态下运行并加5%余量,否则因漏计SGA保留区、结构对齐及内核取整,易触发ORA-27102或大页未使用。

别手算 vm.nr_hugepages,必须用 Oracle 官方脚本 hugepages_settings.sh 在数据库已启动状态下运行,并加 5% 余量;否则大概率触发 ORA-27102: out of memory 或大页完全未被使用。
为什么不能直接用 SGA_MAX_SIZE ÷ 2048 手动计算
看似简单,但会漏掉三类真实开销:
- Oracle SGA 内部保留区(如固定 SGA、日志缓冲区对齐边界)
- 部分内存结构(如某些 latch、shared pool 子结构)仍走普通页,但会占用大页槽位
- 内核强制按 2MB 边界向上取整——哪怕只多 1KB,也要占满一整页
实测:6GB SGA 手算得 3072 页,实际需约 3120 页。差这几十页,use_large_pages=only 就直接失败。
怎么正确运行 hugepages_settings.sh
这个脚本不是“看看就行”,它依赖当前运行实例的真实内存映射。常见翻车点:
- 数据库实例没 STARTUP —— 脚本读不到
/proc/<pid>/maps</pid>和v$parameter - 路径错:必须是
$ORACLE_HOME/rdbms/install/hugepages_settings.sh(不是admin/下旧版) - 权限不足:必须以
oracle用户执行,且该用户要有读/proc的权限
运行后找输出里这行:Recommended setting: vm.nr_hugepages=XXXX。别直接抄这个数——建议设为 ceil(XXXX × 1.05)。例如输出 3140,就设 3297。
改完 sysctl.conf 还要盯哪几件事
只改 vm.nr_hugepages 是最常见翻车点。以下四项缺一不可:
-
vm.hugetlb_shm_group = <oinstall_gid></oinstall_gid>:填id -g oinstall查出的 GID,否则 Oracle 进程无权绑定大页 -
kernel.shmmax和kernel.shmall必须 ≥ SGA 实际大小(单位字节 / 页),否则共享内存段申请失败 - 执行
sysctl -p后必须确认无报错;有警告或错误必须当场解决
另外两个关键动作常被跳过:echo never > /sys/kernel/mm/transparent_hugepage/enabled(禁用 THP),以及在 limits.conf 中为 oracle 用户设置 memlock unlimited。
多实例或混部环境怎么累加
一台机器跑 Oracle + MySQL + openGauss?hugepages_settings.sh 只管 Oracle,其他得手动加:
- Oracle 部分:用脚本得出值(如 3140)
- MySQL:按
innodb_buffer_pool_size估算,每 2MB 对应 1 页(例如 2GB → +1024 页) - openGauss:重点看
shared_buffers,同样按 2MB/页换算(例如 4GB → +2048 页)
总和后统一加 5% 余量,再写入 vm.nr_hugepages。注意:Linux 内核不会动态回收已分配但未使用的 vm.nr_hugepages 给新服务,所以必须一次性配足。
最易被忽略的是 HugePages_Rsvd 值——它为 0 就代表 Oracle 根本没绑定成功,不管 HugePages_Free 多高都是假象。排查时优先看这个。


















