原文:https://www.modb.pro/db/43710
幾年前一個客戶的Oracle數據庫經常HANG,老白幫他分析了一下,結論是存儲老化,性能不足以支撐現有業務了。正好用戶手頭有個華為S5600T正好從核心系統中換下來放着沒用,就把這個存儲換上去了。換了新存儲后,系統總體確實有所改善。數據庫不會動不動就HANG住,不會出現系統HANG的問題了,但是還是覺得比較慢。出問題時候的AWR報告的片段如下:
從負載上看,每秒的REDO SIZE 37M,還是很高的。邏輯讀的數量不大,不過BLOCK CHANGES很高,物理寫高達1萬+,超過80M/秒,系統的寫壓力比較大。從這個系統上看,應該是存在大批量的數據寫入操作。接下來看看命中率的情況:
命中率情況還是不錯的,因為主要是寫操作,因此DB CACHE的命中率也不高,從上面的LOAD PROFILE看,物理讀實際上也不大,每秒不到20M。再來看看TOP EVENT:
可以看出,讀寫操作的平均延時超過50毫秒,肯定是存在性能問題的。從AWR數據上看,很明顯,本系統是一個寫IO很大的系統,每秒REDO的量達到了 36M/秒以上,每秒的物理寫超過1萬,這在普通的Oracle數據庫系統中是比較少見的。從主要等待事件上看,也主要集中在IO上,從WAIT CLASS分類看,USER I/O也排在第一位,平均等待時間為59MS,SYSTEMI/O的平均等待也達到40MS,從這些指標上看IO是明顯存在問題的。
既然IO存在明顯的問題,那么我們就需要馬上采集下操作系統IO的情況:
APE:/ # sar -d 3 2AIX APE 3 5 00CD36454C00 System configuration: lcpu=32 drives=111 mode=Capped 14:52:11 device %busy avque r+w/s Kbs/s avwait avserv 14:52:14 hdisk44 49 0.0 85 4096 10.0 6.0 hdisk43 65 0.1 138 7329 15.2 4.6 hdisk39 99 0.2 149 8589 40.6 6.7 hdisk38 30 0.8 303 3081 86.5 1.0 hdisk40 99 0.5 210 11196 60.9 4.7 hdisk42 99 0.9 346 13998 76.2 2.9 |
從上述指標上看,IOPS和吞吐量都不算太高,但是平均響應時間(avwait+avserv)確實很高,達到幾十毫秒。這和AWR報告看到的數據是吻合的。於是找存儲工程師參與分析。存儲管理員認為存儲沒問題,負載很輕,從存儲監控上看到的響應時間也很正常,在幾個毫秒。這恐怕是DBA經常遇到的問題了,到底是存儲工程師在推諉呢還是實際情況就是這樣的,存儲沒問題,但是OS層面表現出慢呢?對於sar的數據,很多DBA總是先去看busy%這個指標,一看很多盤都已經是99% busy了,那可不得了了,存儲出現瓶頸了。實際上對於現在的系統而言,busy%這個指標的可參考性並不大,后面的指標更能看出問題。Avque指的是平均隊列的長度,有多少IO在隊列中等待。再后面一列是IOPS,再后面是吞吐量,最后兩列一列是平均等待時間,也就是在隊列中等待IO的時間,和平均服務時間,也就是IO請求發出后,從后端返回的時間。我們通過這些指標實際上是可以區分IO等待是在前端系統端還是后端存儲端的。AVSERV是存儲到OS之間的端到端服務時間,從上面的指標上看,確實也不大,只有幾個毫秒,所以說存儲工程師的說法可能是對的,存儲端並不慢。而avwait是IO在前端的等待時間,這個指標是相當高的,這說明很可能IO並沒有下到存儲上,而是在前端OS層面出現了等待。對於AIX系統而言,這個等待很大可能是和QUEUE_DEPTH參數設置不當有關的。為了進一步確認是否QUEUE_DEPTH不足引起了問題,在AIX系統上,可以用iostat–D去分析:
APE:/ # iostat -D System configuration: lcpu=32 drives=111 paths=4 vdisks=0 hdisk44 xfer: %tm_act bps tps bread bwrtn 21.9 4.1M 160.3 2.1M 2.0M read: rps avgserv minserv maxserv timeouts fails 28.8 5.6 0.1 1.2S 0 0 write: wps avgserv minserv maxserv timeouts fails 131.5 0.4 0.2 1.7S 0 0 queue: avgtime mintime maxtime avgwqsz avgsqsz sqfull 68.1 0.0 9.2S 12.0 0.0 160.3
|
AIX系統的iostat -D是一個十分強大的IO性能分析工具。我們從read這行開始看,平均每秒28.8次讀,平均存儲上返回的服務時間是5.6毫秒,最小是0.1毫秒,最大1.2秒,沒有超時和錯誤(如果這兩列有值,就要十分關注了)。再來看write,平均每秒131.5,平均存儲的服務響應時間是0.4毫秒,這個值為什么比讀的平均值小這么多呢?大家印象里的寫的成本要遠大於讀。實際上這是存儲系統的特點,因為讀數據的時候有可能命中在CACHE里,也有可能需要從物理磁盤上去讀,所以根據命中率不同以及物理盤的性能不同,肯定都會比直接從CACHE中讀要慢一些,而寫入操作,只要寫緩存沒有滿,那么些IO的延時基本上等同於CACHE的寫IO延時,這是十分快的。大家可以關注最后一行的指標,是IO在隊列里的延時情況,平均是68.1毫秒!!!最小是0毫秒,這個應該是不需要排隊直接從后端存儲獲取數據或者寫入數據了,最大高達9.2秒,平均隊列的深度12。大家關注下最后一個指標:sqfull的指標值,這是設備的緩沖隊列滿的次數(累計值),如果這個指標大於0,說明QUEUE_DEPTH參數的設置是不足的,出現了大量IO隊列滿的情況。從上述數據我們可以比較肯定隊列等待可能是問題的主要原因了。下面我們來看看實際上HDISK的設置是什么樣的:
APE:/ # lsattr -El hdisk44 clr_q no Device CLEARS its Queue on error True location Location Label True lun_id 0x4000000000000 Logical Unit Number ID False max_transfer 0x40000 Maximum TRANSFER Size True node_name 0x2100f84abf591cca FC Node Name False pvid 00cd36456aecb23e0000000000000000 Physical volume identifier False q_err yes Use QERR bit True q_type simple Queuing TYPE True queue_depth 1 Queue DEPTH True reassign_to 120 REASSIGN time out value True rw_timeout 30 READ/WRITE time out value True scsi_id 0xe0 SCSI ID False start_timeout 60 START unit time out valueTrue ww_name 0x2008f84abf591cca FC World Wide Name False |
什么?QUEUE_DEPTH居然是1?其實也沒啥大驚小怪的,在AIX系統下,華為存儲的缺省QUEUE_DEPTH就是1,HDS存儲的缺省值是2,而IBM自己的存儲的缺省值是8,也不知道是不是IBM在故意惡心友商。存儲工程師並沒有幫助用戶設置合理的值。那么這個參數設置為多少合適呢?根據老白的經驗,如果跑Oracle這個參數至少設置為8,高負載的系統可以設置為更大的值,甚至32或者更高(LINUX上缺省是128),不過也不是越高越好,要看你的存儲的能力,如果這個參數很大,存儲沒那么強的能力,也是沒用的,需要一個匹配。既然發現了問題,那么果斷的將參數調整為24,我們來看看優化后的效果,將QUEUE_DEPTH加大到24,再看AWR數據:
看上去IO的性能是不是好了很多,REDO量也上去了,從每秒37M提高到57M左右。其實這時候IO還是有問題,現在壓力下放到存儲上,存儲上看到明顯的性能問題了。下面可以進一步優化,比如QUEUE DEPTH是不是還可以再加大。另外數據能否存放到更多的盤上。給客戶的建議是再多分配2-3個RAID 組,把部分數據分散到多個RAID 組上。實際上隊列深度以前一直是困擾小型機上IO性能的一個問題。這個參數設置太小會有排隊問題,設置太大也並不一定好,如果你的后端存儲能力不足,而設置的隊列深度太大,最終整體IO性能也不見得好。LINUX上,隊列深度缺省是128,通過LINUX的調度策略來智能化調度,因此這個問題在LINUX上不多見。不過如果后端存儲是高端的全閃存陣列,那么128的隊列深度還是不能發揮出后端存儲的能力的,這時候我們還是需要調整隊列深度的。