您好,登錄后才能下訂單哦!
前言
不知不覺,技術人生系列·我和數據中心的故事來到了第四期。小y又和大家見面了!
當您看到業務系統壓測呈現以下波浪形的tps曲線時,你會怎么下手?
Oracle數據庫在11.2.0.3及以上的版本上必須要調整的一個重要的性能相關的參數!
如何在診斷失敗后堅持或快速調整問題甄別方向的技巧!
如何在處理跨團隊/部門的綜合型問題中掌握主動權的一些經驗!
溫馨提示
Part 1
問題來了
小y,有空嗎?幫忙看個awr。
我一會跟你電話說一下情況。
可以看到,壓測時的TPS呈現波浪形,極不穩定。
客戶自己做了很多分析,資源層面,CPU、內存使用率、IO均正常,不過客戶自己也發現了,壓測時后端Oracle數據庫中出現了大量的異常等待,主要是gc類型的等待,客戶懷疑是不是私網交換機有問題。但可惜的是,網絡團隊卻未檢查出異常。
這個問題,他們也請現有的Oracle服務商進行了分析,但問題遲遲沒有解決。這樣一來,離業務系統要求上線的時間越來越近了,客戶的壓力也越來越大!
小y最近一直在跟這個客戶,從心里真心希望能有機會為他們提供服務,所以這樣的機會來了,小y自然是打起了十二分精神,準備開始戰斗。
環境介紹:
操作系統Redhat 64 bit,64C 128G
數據庫 Oracle 11.2.0.3 ,2節點RAC
Part 2
分析過程
我們用DB Time除以Elapsed,可以看到每秒DB TIME達到75!這是極度不正常的。
說明數據庫正在經歷嚴重的等待,需要查看數據庫top等待事件繼續分析。
事件分析
Oracle top 5等待里,gc buffer busy acquire排在第一位,占了51.2%,平均每次等待時間達到驚人的277毫秒!這里的gc buffer busy acquire表示在進程A之前已經有進程B先行向節點2請求同樣的一個數據塊,并且還沒有完成,因此處在等待上。
排在第二位的是log file sync,占了18.58%,平均每次達到293毫秒。這里的log file sync表示當進程發出commit時,需要等lgwr后臺進行將log buffer中的改變向量持久化到磁盤中的redo log中所發生的等待。
排在第三位的是DB CPU,在一個小時的采樣里,總的等待時間是24648秒,也就是說大概占了7顆CPU時間,該服務器配置了64顆CPU,因此平均CPU使用率只用到了10%。這里小y順便提一下,通常情況下,我們期望DB CPU的比例越高越好,這樣就意味著SQL在執行的過程中,幾乎不用發生等待,SQL的響應時間也就越快。但不代表就沒問題,比如高邏輯讀的SQL,如果要操作的數據都在內存中,也會導致DB CPU過高,此時就需要對高邏輯讀的SQL進行優化了,從而降低 DB CPU。
排在第四位的是direct path read,平均等待時間也到了153毫秒。這里的direct path read表示進程直接將數據塊讀入PGA內存而不是讀進buffer cache共享內存。這種情況下,IO的吞吐顯然會更大,每個進程都各自讀各自的哪怕是相同的數據。如果不同的進程同時讀取的是相同的數據,并且讀進共享內存,那么只需要一個進程負責讀取,其他進程直接操作內存中的數據即可,此時IO吞吐會小很多。
排在第五位的是buffer busy wait,平均等待時間到了驚人的499毫秒。這里的buffer busy wait表示當兩個或者兩個以上的進程需要同時對一個數據塊進行寫/寫、寫/讀操作時發生沖突,即熱塊沖突。
看到這里,小Y已經基本知道答案了!
不過從嚴謹的角度,還是要把RAC 2節點的等待事件也稍微過一下。
和節點1相比,沒有buffer busy wait,多了gc current block busy。
總體來說,兩個節點的等待事件差別不大!
看到這里,也許有人會說:
gc等待那么高,是不是把另外一個RAC節點臨時關掉,問題就解決了呢?
首先答案是NO!其次,這樣的做法是生產出現緊急gc性能問題時可以臨時采用的,但是對于這樣一個case,客戶顯然是不接受的。
小y從技術層面來回答下這個問題。
首先,如下圖所示
兩個節點的私網不過是每秒3M,而RAC兩臺服務器為私網配置的是千兆交換機。
其次,RAC兩個節點的CPU和內存均處于低位,也就沒有出現因為資源問題導致一個節點運行緩慢,繼而導致無法快速響應另外一個節點的gc請求的情況。
如果是該類問題,我們通常還可以看到gc*congested*類型的等待(擁堵)。
其中bbw即buffer busy wait,
gc即表示gc buffer busy acquire等gc等待。
也許有人會說:
gc等待那么高,還有buffer busy wait等待,如果SQL效率足夠高,那么訪問的數據塊就少了,那么進程發生gc請求的個數就很少,同時由于讀/寫造成的熱塊沖突自然也就沒了。
答案是NO!
見下圖,可以看到該應用還是寫的相當不錯的,大部分SQL都控制在100個邏輯讀以下,只有3個SQL的邏輯讀在幾千到幾萬,這樣的SQL效率和邏輯讀數量不足以導致如此高的gc/bbw等待!另外,落到SQL效率不高這個點上,是沒有辦法解釋log file sync/direct path read也處于平均單次長時間等待的!錯誤的方向是不能解決根本問題的!也就是說,即使你再花精力優化掉這幾個邏輯讀稍微高一些的SQL,壓測的問題還是會依然存在,因為這不是根本原因,優化SQL對于這個CASE而言是錦上添花而非雪中送炭!
也許有人會說,會不會有這樣一種可能:
先是direct path read導致IO帶寬被占滿
說明:多個進程把數據塊讀進PGA私有內存而不是buffer cache共享內存,以多塊讀16計算,每個BLOCK 8K,每個進程可以讀取30M左右,15個以上的進程同時多塊讀就可以把hba卡帶寬占滿,設置10949 event可禁止該特性。
由于IO帶寬被占滿,影響了lgwr寫日志的響應時間,繼而導致log file sync等待長。
而log file sync又是gc和buffer busy wait的一個環節,從而將gc和buffer busy等待時間拉高,因此出現了AWR報告的等待?
首先,可以做出該假設的朋友,可以發小y發一份簡歷,說明你對數據庫有非常深入的理解,并且有非常豐富的TroubleShooting經驗,而且也已經不在割裂的分析問題的層面上了!
歡迎你加入中亦科技DBA團隊!來了就是兄弟,我們一起并肩戰斗,一起挑戰各種疑難問題,一起分享收益!
簡歷請發至51994106@qq.com
那么Log file sync和gc有什么關系呢?
引用一張RAC SG的圖,其中原理如下圖所示
從上圖可以看到:
gc類的請求,在第二步中包含了lgwr進程寫日志的過程,
即log file sync是gc請求的一個子步驟,嚴格來說,該步驟叫gc log flush sync.
但答案依然是NO!
小y這兩分鐘里如同上述的分析一樣,飛速的進行著各種假設和排除、問題串聯。
很快小y就鎖定了問題的分析方向——那就是要把分析焦點放在log file sync等待上!
原因很簡單,通過分析top 5等待,不難看到,他們之間是有關聯關系的:
log file sync是gc和buffer busy wait的一個環節!(見2.3.3中的圖)
如果log file sync等待解決了,自然gc*等待和buffer busy wait等待也就下去了!
問題也就得到解決了!
從上文,我們已經知道,“log file sync”等待事件表示:
當進程發出commit時,需要等lgwr后臺進行將log buffer中的改變向量持久化到磁盤中的redo log的過程中所發生的等待。因此,最常見的是lgwr寫日志寫的慢,或者是因為commit太頻繁所導致!
接下來小y依次檢查了這兩個方面。
ORACLE當中,如果lgwr寫日志寫的慢,會體現到log file parallel write單次響應時間慢上。
節點1
節點2
可以看到,兩個節點無論是log file parallel write還是gc log flush sync都只在5個毫秒以下,其中log file parallel write更是只有1毫秒和3毫秒。排除該問題!
接下來檢查commit次數!
如下圖所示,每秒的transactions(commits/rollbacks)只有48個!
小y服務過的一些大型銀行的高并發的核心系統中,包括每秒事務數在10000以上的,log file sync也都控制在10個毫秒以內。所以每秒transactions只有48個是非常小的指標,不至于引起這么嚴重的等待!
分析到了這里,小y已經已經找到本次壓測的根本原因了,只需要調整驗證即可。
建議朋友們,讀到這里也可以先停一下,看看自己是否找到了問題原因。
也就是客戶AWR報告發過來后的兩分鐘,小y告訴他
其實并不奇怪,這樣的case小y在幾年前做大量系統升級到11g時就遇到過N次!客戶很驚訝,他甚至還來不及電話小y,小y怎么可以這樣…
這應該是一個上線前的標配,雖然現象不一樣,但本質上是一個問題。
這也就是小y標題中要重點提示大家的一個重要的數據庫參數。
如果Log file sync等待事件很長,但是lgwr寫日志的時間很快,并且commit次數也不大的話,那就是在發起commit的進程和lgwr之間的通訊環節上出了問題。
關鍵知識點:
ORACLE從11G開始,為lgwr寫日志引入了polling機制,而在以前只有post/wait機制。
同時引入了一個隱含參數,"_use_adaptive_log_file_sync",即在兩個機制之間自適應的切換。在11.2.0.3以下,該參數的默認值為false,即只啟用post/wait機制。
從11.2.0.3開始,該參數的默認值為true,即Oracle會在post/wait機制和polling機制自適應。
Post/wait進制下,lgwr進程在寫完log buffer中的改變向量后,立刻通知待commit的進程,因此log file sync等待時間短,但lgwr相對來說,負擔要重一些。畢竟12C以下lgwr進程只有1個,當同時commit的進程比較多的時候,通知待commit的進程也是一種負擔。
Polling模式下,待commit的進程,通知lgwr進程進行寫入操作后,會進入sleep環節,并在timeout后去看是否log buffer中的內容被寫入了磁盤,lgwr進程不再單獨通知待commit的進程寫已經完成。Polling機制下,解放了一部分lgwr的工作,但是會帶來待commit的進程長時間處于log file sync等待下。對于交易型的系統而言,該機制是極度不適用的!
在post/wait和polling機制之間的切換,ORACLE會記錄到lgwr進程的trace當中,如下所示。
當切換到polling模式下時,很容易引起log file sync等待而影響交易的響應時間!
Log file sync switching to polling
……
Log file sync switching to post/wait
在Oracle 11.2.0.3以下,建議關閉自適應log file sync,務必讓lgwr進程運行在post/wait機制下,以確保數據庫性能不會出現大的抖動!關閉的命令如下,可在線修改!因此,小y在這里提示各位
alter system set "_use_adaptive_log_file_sync"=false sid='*';
在線調整參數后,為了安全起見,客戶把兩個節點數據庫都重啟了一遍。
并且重新做了壓力測試,重新收集后的AWR報告如下所示!
看到節點1的這個AWR報告,gc等待和log file sync等待依然存在,并且看上去單次等待的時間更長了!
難道小y的分析出了問題? 或者說,小y這次遇到了好幾個摻雜在一起的問題?冷靜了一下,RAC的問題,切記只看單個節點,因此,小y讓客戶出了節點2的AWR報告,調整后節點2的awr報告如下圖所示:
可以看到:
雖然等待還在,但節點2的log file sync等待沒有了!這說明這次調整還是起到效果了的!
總結一下,這里調整log file sync自適應后,問題還是沒有得到解決,那么回到傳統思路上,最可能的問題那就還是lgwr進程寫日志慢了!雖然awr報告中log file parallel write指標只有幾個毫秒,但是awr報告畢竟是一個工具,提供的只是參考值,因此我們還是要抱著懷疑一切的態度,再來塞查一次!
這一次,我們來實時觀察lgwr進程寫日志的情況。發出SQL語句,結果如下圖所示:
可以看到:
RAC兩個節點中,只有1個節點出現log file parallel write的等待,剛好和前面的所有分析相互吻合!
在state是waiting的情況下,log file parallel等待的seq#都是35693,但是seconds_in_wait達到了21秒。簡單來說,就是lgwr進程寫一個IO需要21秒!
至此,我們可以肯定,IO子系統有問題,需要重點排查IO路徑下的光纖線、SAN交換機、存儲的報錯和性能情況。
節點1上出現明顯的IO ERROR,并且在持續增加!
繼續檢查節點2,發現節點2上沒有任何IO ERROR!
回顧前面的分析,節點2在調整數據庫自適應log file sync為false后,并且沒有出現IO ERROR,因此已經沒有log file sync。
至此,分析結束!所有問題都得到了完美的解釋!
找到原因了,還拿到了說服力極強的證據,客戶終于松了一口氣,不怕存儲團隊不認賬了!
壓測的TPS曲線從原來的波浪形:
Part 3
問題原因和總結和風險提示
該航空客戶業務上線時壓測無法達到并發和響應時間指標的原因在于同時遇到了兩個混在一起的問題:
1)Oracle 11.2.0.3上log file sync默認打開自適應,當切換到polling模式后,導致log file sync等待時間變長,而log file sync是gc和buffer busy wait的一個環節,因此導致大量的等待
小y將"_use_adaptive_log_file_sync"調整為false后,就解決了一部分的log file sync等待的問題
2)由于節點1的光纖線存在質量問題,會導致IO錯誤,繼而導致IO重發,影響了lgwr寫日志的性能。
在調整數據庫參數默認值并且更換光纖線后,問題得到圓滿解決。
壓測的TPS曲線從原來的波浪形
1)對Oracle等待事件不要割裂的來分析
小y在本case中通過梳理等待事件的共同點為log file sync,從而找到了突破口
2)了解不同版本數據庫的特性和行為
小y平時在不斷了解11g的新特性,并且通過大量的故障處理深入理解了這些特性,因此,當log file sync出現的時候,可以很快定位到新特性引起
3)不要完全相信AWR報告,他只是個工具,要懷疑一切去驗證。
在這個case中,awr報告的指標并不能真實反映lgwr寫性能的情況,要懷疑一切
4)一個Oracle服務人員,如果只懂數據庫,就會出現你懷疑這懷疑那,但是其他人根本不認賬的情況,因此必須掌握更多的包括操作系統、存儲、網絡、中間件的技能。當然了,找一家綜合服務能力強的服務商也是不錯的選擇。
在這個case中,小y通過多路徑的命令,找到了直接證據,最終獲得了其他團隊的大力度排查也是這次問題最終解決的關鍵。
風險提示
ORACLE從11G開始,為lgwr寫日志引入了polling機制,而在以前只有post/wait機制。
同時引入了一個隱含參數,"_use_adaptive_log_file_sync",即在兩個機制之間自適應的切換。在11.2.0.3以下,該參數的默認值為false,即只啟用post/wait機制。
從11.2.0.3開始,該參數的默認值為true,即Oracle會在post/wait機制和polling機制自適應。
Post/wait進制下,lgwr進程在寫完log buffer中的改變向量后,立刻通知待commit的進程,因此log file sync等待時間短,但lgwr相對來說,負擔要重一些。畢竟12C以下lgwr進程只有1個,當同時commit的進程比較多的時候,通知待commit的進程也是一種負擔。
Polling模式下,待commit的進程,通知lgwr進程進行寫入操作后,會進入sleep環節,并在timeout后去看是否log buffer中的內容被寫入了磁盤,lgwr進程不再單獨通知待commit的進程寫已經完成。Polling機制下,解放了一部分lgwr的工作,但是會帶來待commit的進程長時間處于log file sync等待下。對于交易型的系統而言,該機制是極度不適用的!
進制之間的切換回記錄到lgwr進程的trace當中,如下所示。
當切換到polling模式下時,很容易引起log file sync等待而影響交易的響應時間!
Log file sync switching to polling
……
Log file sync switching to post/wait
因此,小y在這里提示各位。
在Oracle 11.2.0.3以下,建議關閉自適應log file sync,務必讓lgwr進程運行在post/wait機制下,以確保數據庫不會出現嚴重的性能抖動!關閉的命令如下,可在線修改!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。