HugePages 与 Oracle 内存配置

HugePages 与 Oracle 内存配置

适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07


1. 概述

HugePages 是 Linux 提供的大页内存机制,对 Oracle SGA 性能有显著提升[1]:

特性普通 PageHugePages
页大小4 KB2 MB(x86)/ 1 GB(部分 CPU)
TLB 命中率
页表占用
不可交换是(始终驻留内存)
Oracle 性能一般提升 5-15%

2. 为什么需要 HugePages

2.1 TLB(Translation Lookaside Buffer)

CPU 通过 TLB 缓存虚拟地址到物理地址的映射:

无 HugePages(4KB 页):
8GB SGA = 2,097,152 个 4KB 页
TLB 容量有限(通常 1024 项),命中率低
→ 频繁访问页表 → 性能下降

有 HugePages(2MB 页):
8GB SGA = 4,096 个 2MB 页
TLB 容量足够,命中率高
→ 性能提升 5-15%

2.2 页表占用

8GB SGA,无 HugePages:
- 页表大小约 16MB(每 4KB 页需 8 字节页表项)
- 多个进程共享时,页表占用更大

8GB SGA,有 HugePages:
- 页表大小约 32KB
- 节省 99% 页表内存

2.3 不可交换(Swap)

HugePages 永远驻留物理内存,不会被换出,避免 SGA 被 swap 导致性能急剧下降。


3. 配置 HugePages

3.1 计算 HugePages 数量

# 公式:
# HugePages 数 = (SGA_SIZE + 1MB) / HUGE_PAGE_SIZE
# 
# 例:SGA = 8GB, HugePages = 2MB
# HugePages 数 = (8192 + 1) / 2 = 4097(向上取整)

# 推荐预留 10-20% 余量
# 8GB SGA → 约 4500 个 HugePages

3.2 系统参数配置

# /etc/sysctl.conf
vm.nr_hugepages = 4500

# 应用配置
sysctl -p

****** 验证
grep Huge /proc/meminfo
# HugePages_Total:  4500
# HugePages_Free:   4500
# HugePages_Rsvd:   0
# Hugepagesize:     2048 kB

3.3 用户资源限制

# /etc/security/limits.conf
oracle soft memlock unlimited
oracle hard memlock unlimited

# 或具体值(KB)
# oracle soft memlock 18874368    # 18GB
# oracle hard memlock 18874368

# 重新登录或重启生效
ulimit -l  # 验证(应显示 unlimited)

3.4 Oracle 参数配置

-- 推荐设置
ALTER SYSTEM SET use_large_pages=ONLY SCOPE=SPFILE;
-- ONLY: 强制使用,不使用则启动失败
-- TRUE: 优先使用,回退到普通页
-- FALSE: 不使用

-- 重启数据库
SHUTDOWN IMMEDIATE;
STARTUP;

3.5 验证

-- 查看参数
SHOW PARAMETER use_large_pages;

-- 警报日志检查
grep "HugePages" $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log
-- 应看到 "HugePages: ... used"
# OS 层验证
grep Huge /proc/meminfo
# HugePages_Total:  4500
# HugePages_Free:   200   ← 已分配
# HugePages_Rsvd:   100

4. ASMM 与 HugePages

ASMM 与 HugePages 兼容,是 Linux 生产推荐配置:

ALTER SYSTEM SET sga_target=8G SCOPE=BOTH;
ALTER SYSTEM SET sga_max_size=8G SCOPE=SPFILE;
ALTER SYSTEM SET use_large_pages=ONLY SCOPE=SPFILE;

-- 所有 SGA 子组件设为 0
ALTER SYSTEM SET db_cache_size=0 SCOPE=BOTH;
ALTER SYSTEM SET shared_pool_size=0 SCOPE=BOTH;
ALTER SYSTEM SET large_pool_size=0 SCOPE=BOTH;
ALTER SYSTEM SET java_pool_size=0 SCOPE=BOTH;
ALTER SYSTEM SET streams_pool_size=0 SCOPE=BOTH;

5. AMM 与 HugePages 冲突

重要:AMM(MEMORY_TARGET不兼容 HugePages[2]:

  • AMM 使用 /dev/shm(POSIX 共享内存)
  • /dev/shm 不支持 HugePages
  • 启用 AMM 后,HugePages 利用率为 0

解决方案:Linux 生产环境使用 ASMM + HugePages。


6. 1GB HugePages(5.x 内核+)

新的 Linux 内核支持 1GB HugePages:

# 检查支持
grep pdp1gb /proc/cpuinfo

# /etc/default/grub
GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=8"

# 重建 grub
grub2-mkconfig -o /boot/grub2/grub.cfg

# 重启验证
grep Huge /proc/meminfo
# Hugepagesize:     1048576 kB

适用场景

  • SGA > 100GB
  • 超大内存服务器
  • Oracle Exadata

7. 监控与诊断

7.1 查看使用情况

# OS 层
grep Huge /proc/meminfo

# 查看进程使用 HugePages
cat /proc/$(pgrep ora_pmon_orcl)/smaps | grep -i huge

7.2 Oracle 内部

-- 查看使用模式
SELECT name, value 
FROM v$parameter 
WHERE name = 'use_large_pages';

-- 警报日志分析
grep -A 5 "HugePages" $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log

7.3 性能监控

# 监控 TLB 命中率
perf stat -e dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses -p ****** ora_pmon_orcl) sleep 10

8. 常见坑与排错

8.1 ORA-27102: out of memory

现象:使用 use_large_pages=ONLY 启动失败。

原因:HugePages 数量不足。

修复

# 检查 HugePages 配置
grep Huge /proc/meminfo

# 增大配置
sysctl -w vm.nr_hugepages=5000

# 或改用 TRUE(允许回退)
ALTER SYSTEM SET use_large_pages=TRUE SCOPE=SPFILE;

8.2 HugePages_Free 高但 SGA 未使用

现象:HugePages 配置充足,但 Oracle 没用。

排查

# 1. 检查 use_large_pages 参数
sqlplus / as sysdba
SHOW PARAMETER use_large_pages

# 2. 检查 memlock 限制
ulimit -l
# 应为 unlimited 或足够大的值

# 3. 检查是否启用了 AMM
SHOW PARAMETER memory_target
# 若有值,AMM 会阻止 HugePages

修复

-- 关闭 AMM
ALTER SYSTEM SET memory_target=0 SCOPE=SPFILE;
ALTER SYSTEM SET sga_target=8G SCOPE=BOTH;
ALTER SYSTEM SET use_large_pages=ONLY SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;

8.3 AMM 切换到 ASMM 后性能下降

现象:切换后 HugePages 未启用。

原因:未配置 use_large_pages

修复

ALTER SYSTEM SET use_large_pages=ONLY SCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;

8.4 容器中无法使用 HugePages

现象:Docker 容器中启动 Oracle 报 HugePages 错误。

修复

  • 容器启动时映射 HugePages:--privileged + 挂载
  • 或容器中使用 use_large_pages=FALSE

8.5 SGA 扩展时 HugePages 不足

现象:ASMM 自动扩展 SGA 时失败。

修复:预留充足 HugePages(10-20% 余量)。


9. 最佳实践

  1. Linux 生产用 ASMM + HugePages:性能与稳定最佳
  2. 预留 10-20% 余量:避免 ASMM 扩展失败
  3. use_large_pages=ONLY:强制使用,及时发现问题
  4. memlock=unlimited:避免用户资源限制
  5. 避免 AMM:Linux 上 AMM 不兼容 HugePages
  6. 超大数据库用 1GB HugePages:SGA > 100GB
  7. 定期监控grep Huge /proc/meminfo
  8. 集群统一配置:RAC 所有节点一致

10. 参考资料

[1] Oracle Support Note 361649.1, “HugePages on Oracle Linux 64-bit” https://support.oracle.com/epmos/faces/DocumentDisplay?id=361649.1

[2] Oracle Database Administrator’s Guide 19c, “Managing Memory” https://docs.oracle.com/en/database/oracle/oracle-database/19/admin/managing-memory.html

[3] Linux Kernel Documentation, “hugetlbpage.txt” https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt