Linux上設定大記憶體頁解決kswapd0進程過渡消耗cpusys的問題
環境:SLES11 SP4 + Oracle 11.2.0.4
新搭建測試資料庫,跑了兩天左右發現一個名為kswapd0的進程竟然佔用了1個cpu資源(該主機一共只有2個cpu),而且幾乎都耗在cpusys上。
如所示:
圖1
網上搜尋得知kswapd0是一個核心進程,用來處理頁的交換,當OS的可用記憶體小於閥值時,kswapd會將部分進程的頁從實體記憶體交換到swap上,這個閥值如何確定,頗費周折的找尋了一番仍然沒有結果,至少在SLES 11這個版本下打消了我通過修改閥值來阻止kswapd0進程過渡活躍地消耗cpusys的解決思路。
從資料庫層面入手,首先檢查SGA是否被lock在了記憶體裡
SQL> show parameter lock_sga
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
lock_sga boolean TRUE
SQL>
OS層面再double check一下,確實lock住了
oracle@cspdb1:~> ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 196611 oracle 640 16777216 29 locked <--確實lock住了
0x00000000 229380 oracle 640 1560281088 29 locked
0xf8e2566c 262149 oracle 640 2097152 29 locked
OS層面檢查實體記憶體尚有空閑,而真正的swap動作發生的次數並不多,不然應用早就來投訴了
圖4
圖5
從上述檢查結果我們初步可以判斷: 資料庫的SGA確被鎖定在了實體記憶體裡,kswapd0雖然辛勤勞作(佔去了一個cpu資源)但產出卻很少(被swap出來的頁很少)
該伺服器上除了oracle db外,並沒有其它應用,db上的會話數也只有幾十個,因此最大的記憶體空間還是SGA,想起之前曾經在AIX上啟用過大記憶體頁,最大的好處當然是提供更大size的連續頁塊,減少頁表在記憶體裡的佔用空間,加快頁表的搜尋速度,還有一個好處就是大記憶體頁永遠不會被swap out
為排除SGA可能會被換出實體記憶體或者至少避免kswapd0進程對SGA地區進行的無謂掃描來檢測是否有能被swap out的頁,我們按照如下步驟啟用大記憶體頁
###1、設定/etc/security/limits.conf以及設定後的檢查
* soft memlock unlimited
* hard memlock unlimited
---以oracle登入主機運行檢查上述設定是否生效
oracle@cspdb1:~> ulimit -Hl
unlimited
oracle@cspdb1:~> ulimit -Sl
unlimited
###2、確認沒有啟用AMM,因為AMM和lock_sga不相容
set linesize 100
col name format a30
col value format a30
select name,value from v$system_parameter where name in ('memory_target','memory_max_target','lock_sga');
NAME VALUE
------------------------------ ------------------------------
lock_sga TRUE
memory_target 0
memory_max_target 0
---如果AMM參數或者lock_sga設定不符合要求,可以按照如下步驟重設
SQL> alter system reset memory_max_target;
SQL> alter system reset memory_target;
SQL> alter system set lock_sga=true scope=spfile;
###3、設定大記憶體頁
---計算大記憶體頁的數量,注意執行這一步的時候必須保證執行個體至少啟動到nomount狀態
oracle@cspdb1:~> ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 196611 oracle 640 16777216 29 locked
0x00000000 229380 oracle 640 1560281088 29 locked
0xf8e2566c 262149 oracle 640 2097152 29 locked
oracle@cspdb1:~> cat /proc/meminfo | grep Hugepagesize
Hugepagesize: 2048 kB
最終需要的hugepages=(16777216/2048/1024+1)+(1560281088/2048/1024+1)+(2097152/2048/1024+1)=756
---在/etc/sysctl.conf裡加入
vm.nr_hugepages=756
###4、重啟資料庫執行個體與主機,檢查大記憶體頁設定是否生效
sqlplus '/as sysdba'
shutdown immediate
init 6
cspdb1:~ # sysctl -n vm.nr_hugepages
756
oracle@cspdb1:~> grep HugePages /proc/meminfo
AnonHugePages: 45056 kB
HugePages_Total: 756
HugePages_Free: 756
HugePages_Rsvd: 0
HugePages_Surp: 0
startup
oracle@cspdb1:~> ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 196611 oracle 640 16777216 27 <---狀態從locked變為空白值了,說明大頁天生不會被swapout,所以不care lock_sga的設定:)
0x00000000 229380 oracle 640 1560281088 27
0xf8e2566c 262149 oracle 640 2097152 27
cspdb1:~ # grep HugePages /proc/meminfo
AnonHugePages: 67584 kB
HugePages_Total: 756
HugePages_Free: 623 <---Free < Total,說明已經有huge page被使用了
HugePages_Rsvd: 620
HugePages_Surp: 0
過去一周了kswapd0進程沒有再冒泡上來,詳見
圖6
以下是我對這個現象原因的猜測:當SGA以普通頁的形式存在於記憶體中的時候,雖然lock_sga=TRUE,但仍然無法阻止kswapd0進程對於sga記憶體地區的不斷掃描當然結果是不會有page會被swap out,因為lock_sga=TRUE。但這一過程中存在較多的核心級調用所以kswapd0進程會佔用大量的cpusys資源。所以徹底的方法就是啟用大記憶體頁。
本文永久更新連結地址: