必须用 oracle 官方脚本 hugepages_settings.sh 在数据库已启动状态下运行并加 5% 余量,因其能读取 sga 固定保留区、shared pool 子结构及内核对齐等隐性开销,手算会导致 ora-27102 或大页未启用。
必须用 oracle 官方脚本 hugepages_settings.sh 在数据库已启动状态下运行,并加 5% 余量;手算 vm.nr_hugepages 几乎必然导致 ora-27102: out of memory 或大页完全未被使用。
为什么不能直接用 sga_max_size ÷ 2048 手动计算
看似数学上成立,但 Oracle SGA 内部存在三类隐性开销,hugepages_settings.sh 能读到而人眼看不到:
- SGA 固定保留区(如固定 SGA、日志缓冲区对齐边界)额外占页
- 部分 shared pool 子结构或 latch 占用大页槽位,但不计入 SGA 可见大小
- 内核强制按 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=3140。别抄开头说明文字,也别抄其他行。
多实例或混部环境怎么累加 vm.nr_hugepages
hugepages_settings.sh 只管 Oracle 实例,MySQL、openGauss 等必须手动估算后统一加总:
- Oracle:运行脚本得值(如 3140),再 ×1.05 向上取整 → 3297
- MySQL:按
innodb_buffer_pool_size估算,每 2MB 对应 1 页(如 2GB → +1024) - openGauss:按
shared_buffers估算,同样 2MB/页(如 4GB → +2048)
所有服务的大页需求必须一次性写入 /etc/sysctl.conf 的 vm.nr_hugepages。Linux 内核不会回收已分配但未使用的 hugepage 给新服务——改一次就得全盘重算。
改完 sysctl.conf 还要配哪些关键参数
只设 vm.nr_hugepages 是不够的,缺下面三项,ORA-27102 或静默退回到普通页几乎必然发生:
-
vm.hugetlb_shm_group = <oinstall_gid></oinstall_gid>:填id -g oinstall查出的 GID,否则 Oracle 进程无权绑定大页 -
kernel.shmmax和kernel.shmall:都必须 ≥ SGA 实际字节数(单位:字节 / 页),否则共享内存段申请失败
改完必须执行 sysctl -p 并确认无报错。输出里若出现 error: 或警告,必须当场解决——别信“改了就生效”。
最易被忽略的点:HugePages_Free 高 ≠ 大页在用,恰恰相反——如果它长期接近 HugePages_Total 且 HugePages_Rsvd 为 0,说明 Oracle 根本没绑定成功。真正有效的信号是 HugePages_Rsvd > 0 且 HugePages_Free 显著下降。











