环境:SLES11 SP4 + oracle 11.2.0.4
新搭建测试数据库,跑了两天左右发现一个名为kswapd0的进程竟然占用了1个cpu资源(该主机一共只有2个cpu),而且几乎都耗在cpusys上。
如下图所示:
图1
![](http://img.blog.itpub.net/blog/attachment/201607/12/53956_14682914629yrY.jpg?x-oss-process=style/bb)
网上搜索得知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
![](http://img.blog.itpub.net/blog/attachment/201607/12/53956_1468291510HGJF.jpg?x-oss-process=style/bb)
图5
![](http://img.blog.itpub.net/blog/attachment/201607/12/53956_14682915272w5r.jpg?x-oss-process=style/bb)
从上述检查结果我们初步可以判断: 数据库的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
![](http://img.blog.itpub.net/blog/attachment/201607/12/53956_1468291590KdNy.jpg?x-oss-process=style/bb)
以下是我对这个现象原因的猜测:当SGA以普通页的形式存在于内存中的时候,虽然lock_sga=TRUE,但仍然无法阻止kswapd0进程对于sga内存区域的不断扫描当然结果是不会有page会被swap out,因为lock_sga=TRUE。但这一过程中存在较多的内核级调用所以kswapd0进程会占用大量的cpusys资源。所以彻底的方法就是启用大内存页。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/53956/viewspace-2121890/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/53956/viewspace-2121890/