oracle的一些等待事件

victorymoshui發表於2009-11-03
Oracle的等待事件是衡量Oracle執行狀況的重要依據及指標。等待事件的概念是在Oracle7.0.1.2中引入的,大致有100個等待事件。在Oracle 8.0中這個數目增加到了大約150個,在Oracle8i中大約有200個事件,在Oracle9i中大約有360個等待事件。主要有兩種類別的等待事件,即空閒(idle)等待事件和非空閒(non-idle)等待事件。

  空閒事件指Oracle正等待某種工作,在診斷和優化資料庫的時候,我們不用過多注意這部分事件。

  常見的空閒事件有:

  • dispatcher timer

  • lock element cleanup

  • Null event

  • parallel query dequeue wait

  • parallel query idle wait - Slaves

  • pipe get

  • PL/SQL lock timer

  • pmon timer- pmon

  • rdbms ipc message

  • slave wait

  • smon timer

  • SQL*Net break/reset to client

  • SQL*Net message from client

  • SQL*Net message to client

  • SQL*Net more data to client

  • virtual circuit status

  • client message

  非空閒等待事件專門針對Oracle的活動,指資料庫任務或應用執行過程中發生的等待,這些等待事件是我們在調整資料庫的時候應該關注與研究的。

  一些常見的非空閒等待事件有:

  • db file scattered read

  • db file sequential read

  • buffer busy waits

  • free buffer waits

  • enqueue

  • latch free

  • log file parallel write

  • log file sync

  1. db file scattered read-DB 檔案分散讀取

  這種情況通常顯示與全表掃描相關的等待。當資料庫進行全表掃時,基於效能的考慮,資料會分散(scattered)讀入Buffer Cache。如果這個等待事件比較顯著,可能說明對於某些全表掃描的表,沒有建立索引或者沒有建立合適的索引,我們可能需要檢查這些資料表已確定是否進行了正確的設定。

  然而這個等待事件不一定意味著效能低下,在某些條件下Oracle 會主動使用全表掃描來替換索引掃描以提高效能,這和訪問的資料量有關,在CBO 下Oracle 會進行更為智慧的選擇,在RBO 下Oracle 更傾向於使用索引。

  因為全表掃描被置於LRU(Least Recently Used,最近最少適用)列表的冷端(cold end),對於頻繁訪問的較小的資料表,可以選擇把他們Cache 到記憶體中,以避免反覆讀取。

  當這個等待事件比較顯著時,可以結合v$session_longops 動態效能檢視來進行診斷,該檢視中記錄了長時間(執行時間超過6 秒的)執行的事物,可能很多是全表掃描操作(不管怎樣,這部分資訊都是值得我們注意的)。

2. db file sequential read-DB 檔案順序讀取。

  這一事件通常顯示與單個資料塊相關的讀取操作(如索引讀取)。如果這個等待事件比較顯著,可能表示在多表連線中,表的連線順序存在問題,可能沒有正確的使用驅動表;或者可能說明不加選擇地進行索引。

  在大多數情況下我們說,通過索引可以更為快速的獲取記錄,所以對於一個編碼規範、調整良好的資料庫,這個等待很大是很正常的。但是在很多情況下,使用索引並不是最佳的選擇,比如讀取較大表中大量的資料,全表掃描可能會明顯快於索引掃描,所以在開發中我們就應該注意,對於這樣的查詢應該進行避免使用索引掃描。

  3. Free Buffer-釋放緩衝區

  這個等待事件表明系統正在等待記憶體中的可用空間,這說明當前Buffer 中已經沒有Free 的記憶體空間。如果應用設計良好,SQL 書寫規範,充分繫結變數,那這種等待可能說明Buffer Cache 設定的偏小,你可能需要增大DB_BUFFER_CACHE。

  Free Buffer 等待可能說明DBWR 的寫出速度不夠,或者磁碟存在嚴重的競爭,可以需要考慮增加檢查點、使用更多的DBWR 程式,或者增加物理磁碟的數量,分散負載,平衡IO。

  4. Buffer Busy-緩衝區忙

  該等待事件表示正在等待一個以unshareable方式使用的緩衝區,或者表示當前正在被讀入buffer cache。一般來說Buffer Busy Wait不應大於1%。檢查緩衝等待統計部分(或V$WAITSTAT),看一下等待是否位於段頭(Segment Header)。如果是,可以考慮增加自由列表(freelist,對於Oracle8i DMT)或者增加freelist groups(在很多時候這個調整是立竿見影的,在8.1.6之前,這個freelists引數不能動態修改;在8.1.6及以後版本,動態修改feelists需要設定COMPATIBLE至少為8.1.6).

  如果這一等待位於undo header,可以通過增加回滾段(rollback segment)來解決緩衝區的問題。如果等待位於undo block上,我們可能需要檢查相關應用,適當減少大規模的一致性讀取,或者降低一致性讀取(consistent read)的表中的資料密度或者增大DB_CACHE_SIZE。

  如果等待處於data block,可以考慮將頻繁併發訪問的表或資料移到另一資料塊或者進行更大範圍的分佈(可以增加pctfree值 ,擴大資料分佈,減少競爭),以避開這個"熱點"資料塊,或者可以考慮增加表中的自由列表或使用本地化管理的表空間(Locally Managed Tablespaces)。

  如果等待處於索引塊,應該考慮重建索引、分割索引或使用反向鍵索引。為了防止與資料塊相關的緩衝忙等待,也可以使用較小的塊:在這種情況下,單個塊中的記錄就較少,所以這個塊就不是那麼"繁忙";或者可以設定更大的pctfree,使資料擴大物理分佈,減少記錄間的熱點競爭。

  在執行DML (insert/update/ delete)時,Oracle向資料塊中寫入資訊,對於多事務併發訪問的資料表,關於ITL的競爭和等待可能出現,為了減少這個等待,可以增加initrans,使用多個ITL槽。在Oracle9i 中,引入了一個新概念:ASSM(Segment Space Management Auto)。通過這個新特性Oracle 使用點陣圖來管理空間使用。

  ASSM 結合LMT 徹底改變了Oracle 的儲存機制,點陣圖freelist 能夠減輕緩衝區忙等待(buffer busy wait),這個問題在Oracle9i 以前的版本里曾是一個嚴重的問題。

  Oracle 宣稱ASSM 顯著地提高了DML 併發操作的效能,因為(同一個)點陣圖的不同部分可以被同時使用,這樣就消除了尋找剩餘空間的序列化。根據Oracle 的測試結果,使用點陣圖freelist 會消除所有分段頭部(對資源)的爭奪,還能獲得超快的併發插入操作。在Oracle9i 之中,Buffer Busy wait 不再常見!

5. latch free-latch 釋放

  latch是一種低階排隊機制,用於保護SGA中共享記憶體結構。latch就像是一種快速地被獲取和釋放的記憶體鎖。用於防止共享記憶體結構被多個使用者同時訪問。如果latch不可用,就會記錄latch釋放失敗(latch free miss )。有兩種與閂有關的型別:

  ■ 立刻。

  ■ 可以等待。

  假如一個程式試圖在立刻模式下獲得閂,而該閂已經被另外一個程式所持有,如果該閂不能立可用的話,那麼該程式就不會為獲得該閂而等待。它將繼續執行另一個操作。

  大多數latch問題都與以下操作相關:

  沒有很好的是用繫結變數(library cache latch)、重作生成問題(redo allocation latch)、緩衝儲存競爭問題(cache buffers LRU chain),以及buffer cache中的存在"熱點"塊(cache buffers chain)。

  通常我們說,如果想設計一個失敗的系統,不考慮繫結變數,這一個條件就夠了,對於異構性強的系統,不使用繫結變數的後果是極其嚴重的。

  另外也有一些latch等待與bug有關,應當關注Metalink相關bug的公佈及補丁的釋出。當latch miss ratios大於0.5%時,就應當研究這一問題。

  Oracle的latch機制是競爭,其處理類似於網路裡的CSMA/CD,所有使用者程式爭奪latch, 對於願意等待型別(willing-to-wait)的latch,如果一個程式在第一次嘗試中沒有獲得latch,那麼它會等待並且再嘗試一次,如果經過_spin_count次爭奪不能獲得latch, 然後該程式轉入睡眠狀態,持續一段指定長度的時間,然後再次醒來,按順序重複以前的步驟.在8i/9i中預設值是_spin_count=2000。

  如果SQL語句不能調整,在8.1.6版本以上,Oracle提供了一個新的初始化引數: CURSOR_SHARING可以通過設定CURSOR_SHARING = force 在伺服器端強制繫結變數。設定該引數可能會帶來一定的副作用,對於Java的程式,有相關的bug,具體應用應該關注Metalink的bug公告。

  7. Log Buffer Space-日誌緩衝空間

  當你將日誌緩衝(log buffer)產生重做日誌的速度比LGWR 的寫出速度快,或者是當日志切換(log switch)太慢時,就會發生這種等待。這個等待出現時,通常表明redo log buffer 過小,為解決這個問題,可以考慮增大日誌檔案的大小,或者增加日誌緩衝器的大小。

  另外一個可能的原因是磁碟I/O 存在瓶頸,可以考慮使用寫入速度更快的磁碟。在允許的條件下設定可以考慮使用裸裝置來存放日誌檔案,提高寫入效率。在一般的系統中,最低的標準是,不要把日誌檔案和資料檔案存放在一起,因為通常日誌檔案只寫不讀,分離存放可以獲得效能提升。

8. Log File Switch-日誌檔案切換

  當這個等待出現時,表示所有的提交(commit)的請求都需要等待"日誌檔案切換"的完成。

  Log file Switch 主要包含兩個子事件:

  log file switch (archiving needed)

  log file switch (checkpoint incomplete)

  log file switch (archiving needed)

  這個等待事件出現時通常是因為日誌組迴圈寫滿以後,第一個日誌歸檔尚未完成,出現該等待。出現該等待,可能表示io 存在問題。解決辦法:

  可以考慮增大日誌檔案和增加日誌組

  移動歸檔檔案到快速磁碟

  調整log_archive_max_processes .

  log file switch (checkpoint incomplete)-日誌切換(檢查點未完成)

  當你的日誌組都寫完以後,LGWR 試圖寫第一個log file,如果這時資料庫沒有完成寫出記錄在第一個log file 中的dirty 塊時(例如第一個檢查點未完成),該等待事件出現。

  該等待事件通常表示你的DBWR 寫出速度太慢或者IO 存在問題。

  為解決該問題,你可能需要考慮增加額外的DBWR 或者增加你的日誌組或日誌檔案大小。

  9. log file sync-日誌檔案同步

  當一個使用者提交或回滾資料時,LGWR 將會話期的重做由日誌緩衝器寫入到重做日誌中。日誌檔案同步過程必須等待這一過程成功完成。為了減少這種等待事件,可以嘗試一次提交更多的記錄(頻繁的提交會帶來更多的系統開銷)。將重做日誌置於較快的磁碟上,或者交替使用不同物理磁碟上的重做日誌,以降低歸檔對LGWR的影響。

  對於軟RAID,一般來說不要使用RAID 5,RAID5 對於頻繁寫入得系統會帶來較大的效能損失,可以考慮使用檔案系統直接輸入/輸出,或者使用裸裝置(raw device),這樣可以獲得寫入的效能提高。

  10. log file single write該事件僅與寫日誌檔案頭塊相關,通常發生在增加新的組成員和增進序列號時。

  頭塊寫單個進行,因為頭塊的部分資訊是檔案號,每個檔案不同。更新日誌檔案頭這個操作在後臺完成,一般很少出現等待,無需太多關注。

11. log file parallel write

  從log buffer 寫redo 記錄到redo log 檔案,主要指常規寫操作(相對於log file sync)。如果你的Log group 存在多個組成員,當flush log buffer 時,寫操作是並行的,這時候此等待事件可能出現。

  儘管這個寫操作並行處理,直到所有I/O 操作完成該寫操作才會完成(如果你的磁碟支援非同步IO或者使用IO SLAVE,那麼即使只有一個redo log file member,也有可能出現此等待)。

  這個引數和log file sync 時間相比較可以用來衡量log file 的寫入成本。通常稱為同步成本率。

  12. control file parallel write-控制檔案並行寫

  當server 程式更新所有控制檔案時,這個事件可能出現。如果等待很短,可以不用考慮。如果等待時間較長,檢查存放控制檔案的物理磁碟I/O 是否存在瓶頸。

  多個控制檔案是完全相同的拷貝,用於映象以提高安全性。對於業務系統,多個控制檔案應該存放在不同的磁碟上,一般來說三個是足夠的,如果只有兩個物理硬碟,那麼兩個控制檔案也是可以接受的。在同一個磁碟上儲存多個控制檔案是不具備實際意義的。減少這個等待,可以考慮如下方法:

  減少控制檔案的個數(在確保安全的前提下)

  如果系統支援,使用非同步IO

  轉移控制檔案到IO 負擔輕的物理磁碟

  13. control file sequential read/ control file single write 控制檔案連續讀/控制檔案單個寫對單個控制檔案I/O 存在問題時,這兩個事件會出現。如果等待比較明顯,檢查單個控制檔案,看存放位置是否存在I/O 瓶頸。

  14. direct path write-直接路徑寫該等待發生在,系統等待確認所有未完成的非同步I/O 都已寫入磁碟。對於這一寫入等待,我們應該找到I/O 操作最為頻繁的資料檔案(如果有過多的排序操作,很有可能就是臨時檔案),分散負載,加快其寫入操作。

  如果系統存在過多的磁碟排序,會導致臨時表空間操作頻繁,對於這種情況,可以考慮使用Local管理表空間,分成多個小檔案,寫入不同磁碟或者裸裝置。

  16. Idle Event-空閒事件

  最後我們來看幾個空閒等待事件。一般來說,空閒等待是指系統因為無事可做的等待,或者等待使用者的請求或響應等,通常我們可以忽略這些等待事件。空閒事件可以通過stats$idle_event 表查詢得到。

  我們看一下系統的主要空閒等待事件,對這些事件大家應該有個大致的印象,如果你的Top 5 等待事件中,主要都是這些事件,那麼一般來說你的系統是比價清閒的。

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

相關文章