HugePages 与 Oracle 内存配置
HugePages 与 Oracle 内存配置
适用版本:Oracle Database 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
HugePages 是 Linux 提供的大页内存机制,对 Oracle SGA 性能有显著提升[1]:
| 特性 | 普通 Page | HugePages |
|---|---|---|
| 页大小 | 4 KB | 2 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. 最佳实践
- Linux 生产用 ASMM + HugePages:性能与稳定最佳
- 预留 10-20% 余量:避免 ASMM 扩展失败
use_large_pages=ONLY:强制使用,及时发现问题memlock=unlimited:避免用户资源限制- 避免 AMM:Linux 上 AMM 不兼容 HugePages
- 超大数据库用 1GB HugePages:SGA > 100GB
- 定期监控:
grep Huge /proc/meminfo - 集群统一配置: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