oracle 21c rac中启用use_large_pages=only时,必须禁用memory_target、设sga_max_size≤预留hugepages总量(kb)、sga_target≤sga_max_size,且各节点参数严格一致,否则启动失败或运行时静默崩溃。
oracle 21c rac 中 memory_target 或 sga_target 设置不当,配合未启用或配置错误的 hugepages,极易在启动阶段触发 ora-00838 或直接 hang 住实例,甚至导致 crs 无法拉起数据库服务——这不是配置“不优”,而是根本不可启动。
ORA-00838 错误出现时,先别动 sga_target
这个错误明确提示:memory_target 值小于所需最小值。但很多人直接调大 sga_target 或 db_cache_size,结果重启后报同样错误,甚至 CRS 报 CRS-2674: Start of 'ora.<db>.db' failed</db>。
根本原因在于:当启用了 HugePages(且 use_large_pages=only)时,Oracle 启动前会尝试一次性锁定所有 SGA 内存页。若 memory_target 设置过小,或系统未预留足够 HugePages,oracle 进程在分配阶段就会失败,连初始化日志都写不全。
- 查当前 HugePages 配置:
grep Huge /proc/meminfo,重点关注HugePages_Total和HugePages_Free - 确认是否强制使用:
show parameter use_large_pages— 若为only,则HugePages_Total必须 ≥ 实际所需 SGA 大小(单位:KB) - 计算所需 HugePages 数量:向上取整(
sga_max_size÷Hugepagesize),Hugepagesize通常为 2048 KB(2MB) - 不要依赖
memory_target自动管理:RAC 环境中,memory_target和use_large_pages=only是互斥组合,必须禁用前者
调整 HugePages 前必须停掉所有 Oracle 进程
Linux 下 HugePages 是全局静态内存池,一旦分配,进程退出后不会自动释放。残留的 oracle 进程(尤其是僵死的 ora_lms0_*、ora_pmon_*)会持续占用 HugePages,导致你改完 /etc/sysctl.conf 并执行 sysctl -p 后,HugePages_Free 仍为 0。
- 用
ps -eo pid,comm,args | grep oracle找出全部 oracle 进程,逐个kill -9;特别注意grid用户下的ohasd、crsd进程也要停(crsctl stop crs) - 确认无残留:
ipcs -m | grep oracle应为空;cat /proc/meminfo | grep -i huge中HugePages_Free应等于HugePages_Total - 修改
/etc/sysctl.conf:vm.nr_hugepages = 4096(示例值,按需计算),然后sysctl -p - 验证生效:
grep Huge /proc/meminfo中HugePages_Free不为 0,且与Total一致
数据库参数必须匹配 HugePages 模式
启用 HugePages 后,sga_target 和 memory_target 的行为完全不同。Oracle 不再允许动态收缩 SGA 到低于 HugePages 预留总量,否则启动时校验失败。
- 设
use_large_pages=only:必须确保sga_max_size≤ 预留 HugePages 总量(KB),且sga_target≤sga_max_size;memory_target必须设为 0 - 设
use_large_pages=auto:Oracle 会尽量用 HugePages,但允许 fallback 到普通页;此时memory_target可用,但性能不稳定,RAC 中不推荐 - RAC 节点间参数必须严格一致:一个节点设
sga_max_size=12G,另一个设10G,即使都能启动,也会在 clusterware 同步资源时卡住 - 修改后用
sqlplus / as sysdba执行:startup nomount测试 —— 成功即说明 HugePages 分配和参数无冲突
真正容易被忽略的是:HugePages 预留值不是“够用就行”,而是“必须精确覆盖最大可能的 SGA”。RAC 中某节点因负载突增临时扩大 buffer cache,若 HugePages 不足,实例会在运行中 silently crash,日志里只留下一条 ORA-27102: out of memory,没有堆栈,也没有 trace 文件。











