vm.nr_hugepages (頁數),頁大小固定 2MB (x86_64) 或 4MB (x86) — 以 /proc/meminfo 中 Hugepagesize 為準。grep Hugepagesize /proc/meminfo → 假設 4096 KB (4MB)。nr_hugepages ≥ SGA(MB) / Hugepagesize(MB)。
echo 50 > /proc/sys/vm/nr_hugepages
sysctl -w vm.nr_hugepages=50
echo "vm.nr_hugepages=50" >> /etc/sysctl.conf
grep HugePages_Total /proc/meminfo。若顯示值小於設定值,**必須重啟 OS** 讓核心在記憶體未碎片化時分配大頁。HugePages_Total: 50 (50 × 4MB = 200MB 已預留)。編輯 /etc/security/limits.conf:
oracle soft memlock 102400
oracle hard memlock 102400
計算公式:memlock(KB) ≥ HugePages_Total × Hugepagesize(KB),建議給 2 倍緩衝。
例:50 × 4096 = 204,800 KB → 設 102400 (單位 KB) 即 100MB,視實際 SGA 調整。
驗證:su - oracle; ulimit -l → 應顯示 102400。
sqlplus / as sysdba
STARTUP;
-- 觀察 SGA 分配正常
EXIT;
檢查剩餘大頁:grep HugePages_Free /proc/meminfo → 若 HugePages_Free < HugePages_Total 即證明 Oracle 已佔用大頁。
現象:11g 資料庫啟動後
vmstat持續出現si/so(Swap in/out),系統極慢。
Alert Log 無錯誤。
SGA_TARGET=8G, PGA=3G, 物理記憶體 16G, Swap 8G。
原設定 vm.nr_hugepages = 41984 (約 80GB),遠超物理記憶體,導致核心強行鎖定幾乎所有記憶體給 HugePages,剩餘可用記憶體不足,迫使系統頻繁 Swap。
依 SGA 8G 計算:8G / 2MB = 4096 頁。修改 vm.nr_hugepages = 4096,重啟 OS,問題即時消失,Swap 歸零。
來源:MOS Doc ID 401749.1 / 749851.1 (11g AMM 環境不適用)。
#!/bin/bash
# 自動掃描所有共享記憶體段 (ipcs -m) 計算建議 HugePages 值
# 需在資料庫運行、未啟用 AMM 時執行
KERN=$(uname -r | awk -F. '{printf "%d.%d\n",$1,$2}')
HPG_SZ=$(grep Hugepagesize /proc/meminfo | awk '{print $2}')
NUM_PG=0
for SEG_BYTES in $(ipcs -m | awk '{print $5}' | grep "[0-9][0-9]*"); do
MIN_PG=$(echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q)
if [ $MIN_PG -gt 0 ]; then NUM_PG=$(echo "$NUM_PG+$MIN_PG+1" | bc -q); fi
done
RES_BYTES=$(echo "$NUM_PG * $HPG_SZ * 1024" | bc -q)
if [ $RES_BYTES -lt 100000000 ]; then echo "ERROR: Shared memory segments too small"; exit 1; fi
case $KERN in
'2.4') echo "Recommended setting: vm.hugetlb_pool = $(echo "$NUM_PG*$HPG_SZ/1024" | bc -q)" ;;
'2.6') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
*) echo "Unrecognized kernel"; exit 1 ;;
esac
核心提醒:HugePages **不可 Swap、開機即佔用**,設定過大會擠垮系統,務必用腳本精確計算!