必须禁用amm(memory_target)才能启用hugepages,否则oracle忽略大页配置、sga仍走4kb页;因amm动态管理内存边界,而hugepages要求启动时锁定连续物理页,二者内存生命周期模型根本冲突。

必须禁用AMM(MEMORY_TARGET)才能启用HugePages,否则Oracle会直接忽略大页配置,SGA仍走4KB页路径。
为什么MEMORY_TARGET和HugePages互斥
Oracle内核在AMM模式下动态管理SGA/PGA边界,而HugePages要求内存从启动时就锁定为连续物理页——两者内存生命周期模型根本冲突。即使vm.nr_hugepages已设、memlock已放开,只要SPFILE里还存在MEMORY_TARGET或MEMORY_MAX_TARGET,Oracle启动后Large Pages used by this instance始终显示为0。
常见错误现象:
- 执行
grep Huge /proc/meminfo看到HugePages_Free有余量,但Oracle alert log里仍提示Large Pages unused system wide = 0 - 误以为“设置
sga_target就够了”,没删MEMORY_TARGET,导致重启后配置失效
正确做法:
- 不能用
ALTER SYSTEM SET MEMORY_TARGET=0——这会触发ORA-00843报错 - 必须生成pfile:
CREATE PFILE='/tmp/init.ora' FROM SPFILE;,手动删除pfile中memory_target和memory_max_target两行 - 再重建spfile:
CREATE SPFILE FROM PFILE='/tmp/init.ora';,然后重启
memlock限制必须设为unlimited,不能只设数值
Oracle进程需调用mlock()系统调用锁定大页内存,而ulimit -l的单位是KB,若填具体数值(如62914560对应60GB),极易因计算误差或内核保留开销导致锁定失败。更关键的是:RHEL/CentOS 7+默认PAM模块对memlock数值限制有隐式截断,设成数字反而可能被降级为默认值(通常64KB)。
实操建议:
- 编辑
/etc/security/limits.conf,为Oracle用户添加两行:oracle soft memlock unlimitedoracle hard memlock unlimited - 验证是否生效:
su - oracle -c 'ulimit -l',输出必须是unlimited,不是数字或hard limit字样 - 注意:修改后需重新登录或重启Oracle服务进程,仅改配置不重连session无效
计算vm.nr_hugepages时,必须预留缓冲且避开THP干扰
单纯按SGA大小除以2MB取整(如12GB SGA → 6144页)往往不够。内核页表、HugeTLB池管理结构、以及多实例共存场景都会额外消耗大页资源。更危险的是:若系统启用了透明大页(THP),它会与标准HugePages争抢连续内存,导致/proc/sys/vm/nr_hugepages写入成功但实际HugePages_Free不增加。
安全做法:
- 用Oracle官方脚本
hugepages_settings.sh(Doc ID 401749.1)计算基础值,它会扫描当前所有SHM段并向上取整 - 在此基础上额外加5%~10%:例如脚本输出6144,则设
vm.nr_hugepages = 6500 - 强制关闭THP:
echo never > /sys/kernel/mm/transparent_hugepage/enabled,并写入/etc/default/grub的GRUB_CMDLINE_LINUX追加transparent_hugepage=never,再grub2-mkconfig并重启
最易被忽略的点:HugePages分配依赖连续物理内存,而系统运行一段时间后内存碎片化严重。即使free -h显示空闲内存充足,echo 6500 > /proc/sys/vm/nr_hugepages也可能静默失败(HugePages_Free不变)。此时必须重启——静态预分配才是生产环境唯一可靠方式。











