首页 / 数据库 / MySQL / 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资源。所以彻底的方法就是启用大内存页 。 本文永久更新链接地址
收藏该网址