一條關於swap爭用的報警郵件分析(一)

jeanron100發表於2015-11-25
最近這些天有一臺伺服器總是會收到剩餘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多。架構如圖所示

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  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1846836/,如需轉載,請註明出處,否則將追究法律責任。

相關文章