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

lhrbest發表於2016-04-13

楊建榮的學習筆記 | 2016-02-09 22:28

最近收到報警,某一個伺服器的swap空間有些緊張,檢視這臺伺服器上有兩個備庫資料庫例項,當然負載還是很低的。但是目前來看,記憶體已經所剩無幾,所以自然而然會用到swap,而且swap也看起來緊張了,從設計的角度來看,這種方式還是有很大的隱患,一旦需要切換,這臺伺服器還是很有可能出現oom-killer的情況,也就意味著當機。所以從小從大來看這個報警都不能掉以輕心。

使用top檢視的情況如下,可以看到swap已經很緊張了,剩餘記憶體不到300M了。

top - 13:46:44 up 973 days, 3:00, 1 user, load average: 0.23, 0.16, 0.10

Tasks: 884 total, 1 running, 880 sleeping, 0 stopped, 3 zombie

Cpu(s): 0.9%us, 0.6%sy, 0.0%ni, 98.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

Mem: 65923168k total, 65624684k used, 298484k free, 1256944k buffers

Swap: 33554424k total, 23177916k used, 10376508k free, 60284668k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

6821 oracle 20 0 16.2g 57m 53m S 9.9 0.1 3618:47 ora_rsm0_megdb

4768 oracle 20 0 40.9g 109m 94m S 1.3 0.2 18619:36 ora_dia0_tebdb2

檢視當前伺服器的資料庫例項情況,如下,可以結合上面的情況可以看到SGA應該一個是40G,一個是16G.

[oracle@stepay2 ~]$ ps -ef|grep smon

oracle 4784 1 0 2013 ? 00:24:15 ora_smon_tebdb2

oracle 6738 1 0 2014 ? 00:13:26 ora_smon_megdb

oracle 20793 20706 0 13:47 pts/2 00:00:00 grep smon

進一步檢視進行驗證,tebdb2的SGA看似沒有啟用SGA的自動管理。

SQL> show parameter sga

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

lock_sga boolean FALSE

pre_page_sga boolean FALSE

sga_max_size big integer 41472M

sga_target big integer 0

檢視megdb的SGA的情況,是使用了SGA的自動管理的。

SQL> show parameter sga

NAME TYPE VALUE

------------------------------------ ----------- ------------------------------

lock_sga boolean FALSE

pre_page_sga boolean FALSE

sga_max_size big integer 16G

sga_target big integer 16G

當然PGA也會消耗一些記憶體,但是這些消耗應該不會成為瓶頸,但是swap的消耗卻很高。

為什麼SGA+PGA的設定都在範圍之內,但是swap卻總是不夠用呢。

這個時候檢視共享記憶體段的情況,發現其中一個資料庫例項40G的SGA貌似沒有體現出來。

[oracle@stepay2 trace]$ ipcs -m

------ Shared Memory Segments --------

key shmid owner perms bytes nattch status

0x00000000 294912 oracle 640 4096 0

0x00000000 327681 oracle 640 4096 0

0x4ab8364c 360450 oracle 640 4096 0

0x00000000 1769475 oracle 640 100663296 67

0x00000000 1802244 oracle 640 17079205888 67

0xf6d1ab84 1835013 oracle 640 2097152 67

所以對於這種情況,一種改善思路就是開大頁,從目前經歷的絕大多數Linux系統來說,大頁的設定應該是一個標配.當然Oracle官方也提供了相應的指令碼。

我簡單來說一下,指令碼的思路首先是根據核心版本,目前支援2.4,2.6

[oracle@stepay2 trace]$ uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'

2.6

然後得到一個page size的大小,也可以使用root許可權透過getconf PAGESIZE來得到。

[oracle@stepay2 trace]$ grep Hugepagesize /proc/meminfo | awk {'print $2'}

2048

然後透過ipcs –m得到共享記憶體段的情況,然後根據共享記憶體段的資料來計算需要設定的大頁核心引數設定。

[oracle@stepay2 trace]$ ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"

4096

4096

4096

100663296

17079205888

2097152

因為我們的環境是多例項,我們可以設定一個統一的值,比如我們需要設定50G左右的大頁,就可以使用下面的公式進行計算。

MIN_PG=`echo "51200000000/(2048*1024)" | bc -q`

透過上面的公式就會輸出最終建議的大頁設定

[oracle@stepay2 trace]$ echo "51200000000/(2048*1024)" | bc -q

24414

對應的核心引數在核心2.6就是 vm.nr_hugepages=24414

簡單的環境設定交代完畢,然後準備重啟備庫資料庫例項,同時考慮到資源的使用情況,把原來40G的SGA調整為32G,然後把兩個例項都停了之後,swap的使用率一下子降下來了。

Tasks: 821 total, 1 running, 817 sleeping, 0 stopped, 3 zombie

Cpu(s): 0.9%us, 0.4%sy, 0.0%ni, 98.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

Mem: 65923168k total, 53194676k used, 12728492k free, 63904k buffers

Swap: 33554424k total, 32812k used, 33521612k free, 1694992k cached

然後我們重啟,這個時候發現有一個資料庫例項怎麼都啟動不了。

SQL> startup nomount

ORA-27102: out of memory

Linux-x86_64 Error: 28: No space left on device

一般根據經驗這個錯誤主要都是因為核心引數設定的過小導致。

但是檢視了下面的配置,沒有發現問題。

kernel.shmmax = 68719476736

kernel.shmall=16777216

fs.aio-max-nr = 1048576

fs.file-max = 6815744

vm.nr_hugepages= 24414

對於這個問題著實感到奇怪,同時檢視alert日誌也沒有看到任何大頁開啟的資訊。為什麼大頁沒有開啟呢,而且資料庫例項還啟動不了。

這個可以從共享記憶體段的設定情況來做一個簡單的佐證。

[oracle@stepay2 ~]$ ipcs -m

------ Shared Memory Segments --------

key shmid owner perms bytes nattch status

0x00000000 2260995 oracle 640 201326592 0

0x00000000 2293764 oracle 640 32010928128 0

發現其中一個設定為32G的共享記憶體空間已經被使用了,而且更加奇怪的是切換profile使用sqlplus還連線不到這個例項,可見這部分記憶體空間還沒有透過ORACLE_SID和SGA建立對映關係。那麼對於這部分快取空間,可以手工進行清理。

[oracle@stepay2 ~]$ ipcrm -m 2293764

而為什麼大頁沒有開啟呢,這個時候反覆驗證,發現是啟用了自動記憶體管理,明白了這點再來看這個問題一下子就有些恍然大悟了。把這臺伺服器上相關的服務都停了,然後手工清空了剩餘的共享記憶體段。

[oracle@stepay2 ~]$ ipcs -m

------ Shared Memory Segments --------

key shmid owner perms bytes nattch status

0x00000000 2260995 oracle 640 201326592 0

[oracle@stepay2 ~]$ ipcrm -m 2260995

當然如果條件允許,最好重啟一下,如果不能重啟還是使用sysctl –p來設定核心引數生效。

然後再次重啟就沒有任何問題了。

[oracle@stepay2 trace]$ ipcs -m

------ Shared Memory Segments --------

key shmid owner perms bytes nattch status

0x00000000 3506176 oracle 640 100663296 67

0x00000000 3538945 oracle 640 16005464064 67

0xf6d1ab84 3571714 oracle 640 2097152 67

0x00000000 3637251 oracle 640 201326592 66

0x00000000 3670020 oracle 640 32010928128 66

0x4ab8364c 3702789 oracle 640 2097152 66

透過這個細小的案例,我們可以看到其實有些看似細小的警告,如果不加以重視,會逐漸演變為一個大問題。需要提前預警,提前處理。

About Me

....................................................................................................................................................

本文來自於微信公眾號轉載文章,若有侵權,請聯絡小麥苗及時刪除

ITPUB BLOG:http://blog.itpub.net/26736162

QQ:642808185 若加QQ請註明您所正在讀的文章標題

【版權所有,文章允許轉載,但須以連結方式註明源地址,否則追究法律責任】

....................................................................................................................................................

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

相關文章