Oracle在Linux上因THP抖动是因透明大页与Oracle手动内存管理冲突;必须同时禁用/sys/kernel/mm/transparent_hugepage/enabled和defrag并设内核参数transparent_hugepage=never,RAC环境还需重启CRS及所有Oracle进程。
为什么Oracle在Linux上会因THP抖动
linux默认启用的透明大页(thp)会在运行时自动合并4kb页为2mb大页,看似省事,但oracle的内存管理(尤其是sga使用mlock锁定、手动管理页表)和thp的后台扫描线程(khugepaged)存在冲突。典型表现是:数据库响应延迟突增、vmstat里pgmajfault飙升、/proc/vmstat中thp_collapse_alloc或thp_collapse_fail持续增长——这不是负载高,是thp在反复尝试合并/拆分已锁定的oracle内存页。
禁用THP的两种生效级别及优先级
THP有三个控制开关,必须全部关掉才真正禁用,只改其中一两个会失效:
-
/sys/kernel/mm/transparent_hugepage/enabled:运行时开关,设为never可立即停用当前内核的THP合并行为 -
/sys/kernel/mm/transparent_hugepage/defrag:必须同步设为never,否则khugepaged仍会后台扫描并触发内存抖动 - 内核启动参数
transparent_hugepage=never:写入/etc/default/grub的GRUB_CMDLINE_LINUX,重启后持久生效,覆盖所有运行时设置
常见错误是只改enabled,结果defrag还在跑,Oracle照样抖。验证是否彻底禁用,用cat /sys/kernel/mm/transparent_hugepage/enabled和cat /sys/kernel/mm/transparent_hugepage/defrag,两行输出都必须是always [never] madvise中的never被方括号标出。
Oracle RAC环境下的THP禁用陷阱
RAC节点间对THP状态不敏感,但ocssd.bin和evmd.bin进程若在THP启用状态下启动,后续即使禁用THP,其已分配的内存页仍可能残留大页映射,导致节点心跳延迟或CSSD挂起。所以:
- 必须在所有RAC节点上**重启前禁用THP**,不能只做运行时设置
- 禁用后需重启
oracle用户所有进程,包括crsctl stop crs && crsctl start crs,而非仅重启DB实例 - 检查
ps -eo pid,comm,args | grep -E "(ocssd|evmd)"输出中是否有transp字样(旧版内核日志残留),若有,说明进程启动时THP未关闭
有些DBA用echo never > /sys/.../enabled后立刻启库,没重启CRS,抖动照旧——因为ocssd根本没重读内存策略。
验证THP是否真正退出Oracle进程空间
运行时设置或内核参数修改后,得确认Oracle自己的内存页不再被THP干预:
- 查SGA实际页大小:
grep -i "huge\|trans" /proc/$(pgrep -f "ora_smon")/smaps | grep -E "(MMU|Huge)",输出应为空或只有MMUPageSize=4kB,绝不能出现HugePageSize=2048kB - 监控
khugepaged活动:pidstat -t -p $(pgrep khugepaged) 1,CPU使用率应长期为0.00%,而非周期性跳升 - 对比禁用前后
perf stat -e 'mm.khugepaged.*' -a sleep 60,事件计数应从数千次降为0
最容易被忽略的是:禁用THP后没检查Oracle进程自身的smaps,只看/sys路径返回never就以为万事大吉。其实只要进程启动时THP开着,它的页表就可能被标记为“可合并”,后续即使THP关闭,内核仍可能在内存压力下尝试回收这些页——必须确认进程内存视图干净。











