最近接到一個數據庫報警,讓我頗有些意外,這是一個PGA相關的報警。聽起來感覺是應用端的資源調用出了問題。
報警內容大體如下:
報警內容: PGA Alarm on alltest
------------------------------------報警級別: PROBLEM
------------------------------------監控項目: PGA:6118.6這是一個12cR1的環境,是一套測試環境,確切的說是多套環境整合后的一套大的測試環境,里面含有近8個PDB,也就是之前的多個測試環境整合而來。
所以我就簡單進行了排查,首先這個報警是怎么來的,是在Orabbix配置的監控項。
在Zabbix中查看,可以看到這個報警的相關配置。
({Template_Oracle_OLTP:pga.last(0)}*100/{Template_Oracle_OLTP:pga_aggregate_target.last(0)})>95也就意味著PGA的使用率達到了95%以上的時候就觸發報警,這里涉及兩個監控項pga和pga_aggregate_target。
相關的SQL如下,監控項的SQL在Orabbix中是按照 【監控項】.Query的格式展現的。
pga_aggregate_target.Query=select
to_char(decode( unit,'bytes', value/1024/1024, value),'999999999.9')
value from V$PGASTAT where name in 'aggregate PGA target parameter'
pga.Query=select
to_char(decode( unit,'bytes', value/1024/1024, value),'999999999.9')
c對于這個問題,查看數據庫參數,目前的pga設置是6GSQL> show parameter pga
NAME?????? ? ? ? ? ?TYPE??? ? VALUE
----------------------- ----------- --------
pga_aggregate_limit???? big integer 12880M
pga_aggregate_target??? big integer 6440M但是看起來好像有些不大對勁,還有一個生疏的參數pga_aggregate_limit,這個參數是干什么的,其實這是12c中引入的一個參數,對于pga_aggregate_target的補充。怎么理解容易一些呢,pga_aggregate_target是一個基線值,比如設置為6G,如果PGA使用超過了6G還是很難做到管控,就可能導致一些hang,無響應的問題,這個問題在12c中是考慮引進了參數pga_aggregate_limit來完善的,也就是這個參數的值就是一個最終的大小,絕對不能超過。這個參數輸出中,目前的limit值默認給設置為了12G,而原本設置的target值為6G.
目前的報警是PGA使用超過了閾值,那什么樣的應用會導致如此的PGA使用情況呢,這個讓我有些疑惑。一般來說,單個進程的PGA占用量其實不大,多點也就幾十MB而已。當然為了先盡快修復這個問題,我把PGA target的值改為了7G.
然后我們可以直接這樣嘗試定位一下問題,看看占用PGA最多的進程是哪個,依次來排除。
SQL>? select max(pga_max_mem/1024/1024) from v$process;
MAX(PGA_MAX_MEM/1024/1024)
--------------------------
7989.28072結果看到最大進程怎么消耗如此之高,盡管是一個峰值而已。
SQL> select * from
(select
spid,pga_max_mem/1024/1024,pga_alloc_mem/1024/1024,pga_used_mem/1024/1024,program
from v$process order by pga_used_mem desc) where rownum<10;
輸出的數據如下:
SPID?? PGA_MAX_MEM PGA_ALLOC_MEM PGA_USED_MEM PROGRAM
--------- --------------------- ----------------------- -----------
941??? 7989.??? 7989.4??5061.54467 oracle@teststd.test.com (IMCO)
925??? 132??? 39.851?? 37.1080208 oracle@teststd.test.com (ARC0)
931??? 116??? 38.788?? 37.0642586 oracle@teststd.test.com (ARC3)
937??? 36.96??? 33.093??? 31.872448 oracle@teststd.test.com (W000)
9201?? 37.28??? 31.968?? 31.7101784 oracle@teststd.test.com (W00C)
1491?? 32.53??? 32.468?? 31.6490288 oracle@teststd.test.com (W001)
1327?? 33.90??? 31.968?? 31.6361275 oracle@teststd.test.com (W002)
8181?? 32.53??? 31.843?? 31.5896568 oracle@teststd.test.com (W009)
3510?? 32.78??? 32.093?? 31.5785789 oracle@teststd.test.com (W005)
這一下子讓我有些懵,因為最大的進程竟然是IMCO,這是in memory選件的后臺進程。
[oracle@teststd ~]$ ps -ef|grep 941
oracle???? 941???? 1? 0? 2016 ???????? 07:45:21 ora_imco_testdb這樣一來問題就有些詭異了。
SQL> show sga
Total System Global Area 2.0267E+10 bytes
Fixed Size????????????????? 3721272 bytes
Variable Size??????????? 1.1409E+10 bytes
Database Buffers???????? 6643777536 bytes
Redo Buffers?????????????? 63385600 bytes
In-Memory Area?????????? 2147483648 bytes通過SGA的輸出可以看出,In-Memory占用了大概2G的內存空間。
而且這個參數比較讓人糾結的就是無法動態修改,在實例初始化階段才可以修改。
SQL> alter system set inmemory_size=1G;
alter system set inmemory_size=1G
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-02095: specified initialization parameter cannot be modified這樣一個問題,難道是因為imco的特殊性導致了PGA的占用量大步提升,也被歸納算入了。實際上in memory自啟用后就沒有正式啟用,沒有任何表的數據放在IMO里,所以也排除了IMO的一些異常情況。還有一個驗證的方式就是通過Data Guard來對比補充,結果查看備庫的imco進程情況,壓根誒呦發現什么問題。還有一個思路那就是對比其他的12c環境,是否也存在類似的問題,還有一套近期搭建的12cR2的環境,也啟用了IMO,但是IMCO進程的PGA占用量很低。這也符合了一個常規的想法,那么這個問題是怎么造成的呢,我的一個直觀感受就是一個bug.
這個想法在MOS上得到了一個基本的印證,可以參考
IMCO Background Process Keeps Growing in Memory Usage over Time (Doc ID 2106806.1)這里有一個問題需要確認,那就是IMCO的進程占用情況是逐步的增長還是一開始就很高。
這一點上完全可以通過Zabbix的監控圖得到。
查看近一年的PGA變化曲線圖,可發現是在逐步增長。
所以和MOS里面的那個bug吻合度很高。
按照官方的解釋,有3個途徑可以改進這個問題。
1.? Upgrade to 12.2, when available.
2.? Apply the 12.1.0.2.10DBBP patch (or if you apply PSUs instead of DBBPs, apply the 12.1.0.2.160119DBPSU).
3. Apply interim Patch 19159120 for your RDBMS version and OS.目前來看,步驟2已經滿足,只有重啟一下,或者升級到12c了。