這是3月份某客戶的情況,原因是服務器硬件故障後進行更換之後,業務翻譯偶爾出現提交緩慢的情況。我們先來看下awr的情況。
我們可以看到,該系統的load profile信息其實並不高,每秒才21個transaction。先來看看top5events:
從top 5event,我們可以發現,log file sync的avg wait非常之高,高達124ms。大家應該知道,對於絕大多數情況
下,log file sync的平均等待時間是小於5ms的,這個值有點高的離譜。
我們知道,產生log file sync等待的原因有很多。關於log file sync,tanel Poder大神寫過一篇很牛的pdf,大家可以參考下。
這裏我主要引用大神的圖,來簡單描述產生log file sync的原因可能有哪些,首先我們來看下從前端進程提交到最後得到反饋時,以及中間處理的整個流程情況:
從上圖中,我們可以清楚的看到整個流程。這裏可以進行簡單的描述:
1、當user發起一個commit後;
2、前端進程(即Server 進程)會post一個信息給lgwr進程,告訴它,你應該去寫redo buffer了。
3、當LGWR進程得到指示後,開始調用操作系統函數進行物理寫,在進行物理寫的這段時間內,會出現
log file parallel write等待。這裏或許有人會有疑問,爲什麼12c之前只有一個lgwr進程,這裏卻是parallel
write呢?這裏需要說明一下,lgwr進程在將redo buffer中的數據寫出到log file文件中時,也是以batch方式
進程的(實際上,dbwN進程也是batch的模式),有相關的隱含參數控制。
4、當LGWR完成wrtie操作之後,LGWR進程會返回一個信息給前端進程(Server進程),告訴它,我已經寫完了,
你可以完成提交了。
5. user 完成commit操作。
這裏補充一下,這是由於Oracle 日誌寫優先的原則,假設在commit之前redo buffer的相關entry信息不立即寫到redo
log file中,那麼如果數據庫出現crash,那麼這是會丟數據的。
從上面的流程圖,我們其實也可以看到,log file sync和log file parallel write可以說是相互關聯的。換句話講,如果log file parallel write的時間很長,那麼必然導致log file sync等待時間拉長。
我們假設log file parallel write 等待很高,那麼着可能通常是物理磁盤IO的問題,如下:
我們從上圖可以發行,如果LGWR進程在完成IO操作的過程中時間過長,那麼將導致log file parallel write等待升高。
實際上,在整個當用戶發出commit到完成commit的過程中,涉及到很多環節,並不是僅僅只有物理IO會影響log file sync/log file parallel write。還有CPU也會影響Log file sync和log file parallel write。我們再來看個圖:
我們可以看到,上述流程中的4個環節都涉及到CPU的調度,如果在整個事務commit的過程中,系統CPU出現極度緊張,那麼這可能會導致LGWR進程無法獲得CPU,會進行排隊等待,顯然,這勢必將導致log file sync或log file parallel write等待
的升高。
備註:Oracle中還可以通過隱含參數_high_priority_processes 來控制進程獲取CPU的優先級。在一個cpu相對缺乏的系統中,可以通過設置該參數來進行緩解。
最後我們再回到這個案例中來,客戶這裏的環境,我們是可以排除CPU問題。那麼最大的嫌疑可能就是存儲本身的問題,導致IO很慢,然而,實際上這也是可以排除的,大家其實應該注意到前面的Top 5 event了,log file parallel write的平均等待
時間並不高,如果是存儲IO問題,那麼這個event的平均等待時間應該是比較高才對。
我們可以看到log file sync和log file parallel write的waits都是差不多的。但是log file parallel write的avg wait time僅僅只有4ms,這是一個正常的值。也就是說可以我們排除存儲IO問題。
那麼問題是什麼呢 ?我們利用Oracle MOS提供的腳本來查詢下log file sync和log file parallel write等待的分佈情況:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
INST_ID EVENT WAIT_TIME_MILLI WAIT_COUNT ---------- ---------------------------------------- --------------- ---------- 1 log file sync 1 259306 1 log file sync 2 2948999 1 log file sync 4 1865918 1 log file sync 8 173699 1 log file sync 16 43194 1 log file sync 32 6095 1 log file sync 64 1717 1 log file sync 128 2458
1 log file sync 256 5180
1 log file sync 512 9140
1 log file sync 1024 558347
1 log file parallel write 1 5262
1 log file parallel write 2 4502377
1 log file parallel write 4 1319211
1 log file parallel write 8 46055
1 log file parallel write 16 23694
1 log file parallel write 32 3149
1 log file parallel write 64 283
1 log file parallel write 128 267
1 log file parallel write 256 157
1 log file parallel write 512 73
1 log file parallel write 1024 42
1 log file parallel write 2048 39
1 log file parallel write 4096 103
1 log file parallel write 8192 21
1 log file parallel write 16384 22
1 log file parallel write 32768 190
1 log file parallel write 65536 1 |
大家可以簡單的計算一下,其實log file sync和log file parallel write 等待事件,幾乎99%左右的平均等待時間都是
小於等於4ms的,這是屬於正常的情況;然而有少數的情況其等待時間是很長的,例如log file sync最高的單次等待
時間高達1秒,由於偶爾的等待很高,因此將整個log file sync的平均等待時間拉高了。
到最後,問題就比較清楚了,我認爲這是由於主機和存儲之間的鏈路可能出現異常或不穩定導致。臨時的解決方法
將redo logfile 挪到本地磁盤,解決了該問題。
後記:經客戶後面確認,確實是存儲光纖線接口鬆了。 哈哈