转载

linux上设置大内存页解决kswapd0进程过渡消耗cpusys的问题


环境:SLES11 SP4 + oracle 11.2.0.4



新搭建测试数据库,跑了两天左右发现一个名为kswapd0的进程竟然占用了1个cpu资源(该主机一共只有2个cpu),而且几乎都耗在cpusys上。
如下图所示:
图1

linux上设置大内存页解决kswapd0进程过渡消耗cpusys的问题



网上搜索得知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
linux上设置大内存页解决kswapd0进程过渡消耗cpusys的问题


图5
linux上设置大内存页解决kswapd0进程过渡消耗cpusys的问题



从上述检查结果我们初步可以判断: 数据库的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
linux上设置大内存页解决kswapd0进程过渡消耗cpusys的问题



以下是我对这个现象原因的猜测:当SGA以普通页的形式存在于内存中的时候,虽然lock_sga=TRUE,但仍然无法阻止kswapd0进程对于sga内存区域的不断扫描当然结果是不会有page会被swap out,因为lock_sga=TRUE。但这一过程中存在较多的内核级调用所以kswapd0进程会占用大量的cpusys资源。所以彻底的方法就是启用大内存页
正文到此结束
Loading...