转载

一条关于swap争用的报警邮件分析(一)

最近这些天有一台服务器总是会收到剩余swap过低的告警。
邮件内容大体如下:
############
ZABBIX-监控系统:
------------------------------------
报警内容: Lack of free swap space on ora_test_s2_yangjr@10.127.2.xxxx
------------------------------------
报警级别: PROBLEM
------------------------------------
监控项目: Free swap space in %:21.59 %
------------------------------------
报警时间:2015.11.23-04:10:57
简单查看了一下服务器配置,发现是一个32G的服务器,swap空间为8G,目前已经使用6G多。架构如图所示
一条关于swap争用的报警邮件分析(一)
top - 11:56:03 up 152 days,  2:06,  1 user,  load average: 0.53, 0.34, 0.27
Tasks: 338 total,   1 running, 326 sleeping,   0 stopped,  11 zombie
Cpu(s):  5.6%us,  0.0%sy,  0.0%ni, 94.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32949076k total, 32846716k used,   102360k free,   237324k buffers
Swap:  8385920k total,  6427096k used,  1958824k free, 28360876k cached
对于这个,简单分析了一下,原来这台服务器上再运行两个数据库实例
oracle    5606     1  0 Jun24 ?        00:01:12 ora_smon_ctest
oracle   10533     1  0 Jun27 ?        00:01:11 ora_smon_catest
oracle   21950 21560  0 17:54 pts/0    00:00:00 grep smon
从smon初始化的时间来看,这两个数据库实例大概是在7月底启动的,时间有一些先后。
这两个库是11g的DG环境。所以平时主要是会有归档的接收和应用。
为什么会发生swap争用呢,首先想到的就是内存组件的设置问题,是不是设置过大,导致没有富裕的内存资源可用了。
查看数据库实例ctest
SQL> show parameter sga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 12032M
sga_target                           big integer 12032M
SQL> show parameter pga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target                 big integer 4010M
所以对于ctest sga+pga=12G+4G=16G,大体如此。

对于数据库实例catest,内存组件大小为;
SQL> show parameter sg
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 20G
sga_target                           big integer 20G
SQL> show parameter pga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target                 big integer 8530M
所以简单相加就是20G+8G=28G
如此一来,28G+16G=44G,而内存资源只有32G,那剩下的12G是怎么来的。如果排除法,也就只有swap了。
当然数据库层面没有任何的异常,也没有限制sga无法设置成功之类的问题。听起来倒也相安无事。
查看v$dynamic_components得到的信息如下:
catest的内存组件大小为:2G+18G=20G
$sh showbuffer.sh
[oracle@scycard2 dbm_lite]$ sh showbuffer.sh
COMPONENT                       CURRENT_M      MIN_M      MAX_M SPECCIFIED_M LAST_OPER LAST_OPER_TYP  GRANULE_M
------------------------------ ---------- ---------- ---------- ------------ --------- ------------- ----------
shared pool                          2304       2304       2304            0           STATIC                64
large pool                             64         64         64            0           STATIC                64
java pool                              64         64         64            0           STATIC                64
streams pool                            0          0          0            0           STATIC                64
DEFAULT buffer cache                17920      17920      17920        15360           INITIALIZING          64
           
ctest的内存组件大小为:
$ sh showbuffer.sh
COMPONENT                       CURRENT_M      MIN_M      MAX_M SPECCIFIED_M LAST_OPER LAST_OPER_TYP  GRANULE_M
------------------------------ ---------- ---------- ---------- ------------ --------- ------------- ----------
shared pool                          1664       1664       1664            0           STATIC                32
large pool                             64         64         64            0           STATIC                32
java pool                              64         64         64            0           STATIC                32
streams pool                            0          0          0            0           STATIC                32
DEFAULT buffer cache                10176      10176      10176            0           INITIALIZING          32
内存组件大小为1.6G+10G约为12G
所以如此一算,刚好和内存的大小一致。看来尽管sga,pga会显示有一个很大的值,其实还是根据实际的内存资源来分配。
这个时候问题就来了,为什么能够设置sga,pga为一个较高的值,而且数据库中似乎能够验证通过。
这个地方也就只能用kernel层面才可以说清了。
cat /etc/sysctl.conf的配置如下,可以看到配置了shmmax为近100G的最大共享内存段,支持的共享内存段的页数也非常高。shmall还是很高的。
fs.aio-max-nr = 1048576
kernel.shmall = 33554432
kernel.shmmax = 107374182400
kernel.shmmni = 4096
查看当前的session设置的shmmax的值。
# more /proc/sys/kernel/shmmax
107374182400
如果查看共享内存段的内容如下:
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x74010013 2293760    root      600        4          0                       
0x740182d0 2981889    root      600        4          0                       
0x00000000 4194306    oracle    640        134217728  67                      
0x740182cf 2949123    root      600        4          0                       
0x00000000 4227076    oracle    640        21340618752 67                      
0x538bd97c 4259845    oracle    640        2097152    67                      
0x00000000 3768326    oracle    640        67108864   49                      
0x00000000 3801095    oracle    640        12549357568 49                      
0xaf0a22e4 3833864    oracle    640        2097152    49                      
0x6c0109ec 6455305    zabbix    600        995952     6  
所以内核参数的设置还是存在一定的问题,shmmax可以设置为内存的一半或者更高。一般会尝试用内存的80%等
#kernel.shmall = 33554432
#kernel.shmmax = 107374182400

kernel.shmall = 8388608
kernel.shmmax = 32212254720
比如可以设置为一个相对较大的值,使用getconf PAGE_SIZE得到的页大小一般都是4k.
那么我们来简单规范一下。
ctest数据库实例的设置为:
SQL> alter system set sga_max_size=12G scope=spfile;
System altered.
SQL> alter system set sga_target=12G scope=spfile;
System altered.
SQL> show parameter uniq
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                       string      STEST
SQL> show parameter pga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target                 big integer 4G
pga适度改小一些,然后停备库,听备库还有什么方法论吗,那就是看看session的情况,是否有其它额外的session在运行。
SQL> select username,count(*)from v$session group by username;
USERNAME                         COUNT(*)
------------------------------ ----------
                                       42
PUBLIC                                  5
SYS                                     1

SQL> shutdown immediate       之后就需要使用sysctl -p或者重启服务器的方式来设置生效了。        
没有sysctl -p之前,查看shmmax的设置还是100G
$ more /proc/sys/kernel/shmmax
107374182400
设置生效之后,再来看看swap的情况。发现一下子降下来了。
top - 17:34:47 up 154 days,  7:45,  2 users,  load average: 0.33, 0.32, 0.28
Tasks: 211 total,   1 running, 204 sleeping,   0 stopped,   6 zombie
Cpu(s):  0.3%us,  0.3%sy,  0.0%ni, 99.2%id,  0.2%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32949076k total,  3464424k used, 29484652k free,   193008k buffers
Swap:  8385920k total,     4352k used,  8381568k free,  2901552k cached
至于swap的监控,可以使用下面的脚本来做一些简单的分析,还算是比较实用的。
因为环境的swap使用很低,所以可以找一台服务器swap相对较高的,然后使用下面的脚本来分析。
#  for i in $( cd /proc;ls |grep "^[0-9]"|awk ' $0 >100') ;do awk '/Swap:/{a=a+$2}END{print '"$i"',a/1024"M"}' /proc/$i/smaps 2>/dev/null ; done | sort -k2nr | head -10
19119 1503.39M
7520 50.7617M
18216 38.6172M
18218 26.3945M
18212 22.0938M
32219 11.8242M
18174 11.2539M
18286 7.8125M
18214 6.90625M
12507 5.17578M
可以看到哪个进程占用了较高的temp资源情况。
那么这儿问题如何验证,是否内核参数shmmax,shmall设置过高,会有sga_target设置的错觉。
SQL> show parameter sga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 45G
sga_target                           big integer 45G
使用top -c查看的结果如下:
Tasks: 253 total,   1 running, 252 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  16319100k total,  5582080k used, 10737020k free,   429292k buffers
Swap: 16777200k total,    12956k used, 16764244k free,  4402968k cached
ipcs的情况可以参见下面的结果。
$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 6062080    oracle     640        67108864   17                      
0x00000000 6094849    oracle     640        12515803136 17                      
0xfadedb24 6127618    oracle     640        2097152    17                      
0x00000000 6848515    oracle     640        268435456  27                      
0x00000000 6881284    oracle     640        24024973312 27                      
0x00000000 6914053    oracle     640        24024973312 27                      
0xc3655edc 6946823    oracle     640        2097152    27  

正文到此结束
Loading...