Oracle常見等待事件說明
2024-08-29 13:34:43
供稿:網(wǎng)友
 
               Oracle的等待事件是衡量Oracle運行狀況的重要依據(jù)及指標。等待事件的概念是在Oracle7.0.1.2中引入的,大致有100個等待事件。在Oracle 8.0中這個數(shù)目增加到了大約150個,在Oracle8i中大約有200個事件,在Oracle9i中大約有360個等待事件。                                                                                            主要有兩種類別的等待事件,即空閑(idle)等待事件和非空閑(non-idle)等待事件。  空閑事件指Oracle正等待某種工作,在診斷和優(yōu)化數(shù)據(jù)庫的時候,我們不用過多注重這部分事件。  常見的空閑事件有:  • 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的活動,指數(shù)據(jù)庫任務(wù)或應(yīng)用運行過程中發(fā)生的等待,這些等待事件是我們在調(diào)整數(shù)據(jù)庫的時候應(yīng)該關(guān)注與研究的。  一些常見的非空閑等待事件有:  • 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 文件分散讀取  這種情況通常顯示與全表掃描相關(guān)的等待。當數(shù)據(jù)庫進行全表掃時,基于性能的考慮,數(shù)據(jù)會分散(scattered)讀入Buffer Cache。假如這個等待事件比較顯著,可能說明對于某些全表掃描的表,沒有創(chuàng)建索引或者沒有創(chuàng)建合適的索引,我們可能需要檢查這些數(shù)據(jù)表已確定是否進行了正確的設(shè)置。  然而這個等待事件不一定意味著性能低下,在某些條件下Oracle 會主動使用全表掃描來替換索引掃描以提高性能,這和訪問的數(shù)據(jù)量有關(guān),在CBO 下Oracle 會進行更為智能的選擇,在RBO 下Oracle 更傾向于使用索引。  因為全表掃描被置于LRU(Least Recently Used,最近最少適用)列表的冷端(cold end),對于頻繁訪問的較小的數(shù)據(jù)表,可以選擇把他們Cache 到內(nèi)存中,以避免反復(fù)讀取。  當這個等待事件比較顯著時,可以結(jié)合v$session_longops 動態(tài)性能視圖來進行診斷,該視圖中記錄了長時間(運行時間超過6 秒的)運行的事物,可能很多是全表掃描操作(不管怎樣,這部分信息都是值得我們注重的)。    2. db file sequential read-DB 文件順序讀取。  這一事件通常顯示與單個數(shù)據(jù)塊相關(guān)的讀取操作(如索引讀取)。假如這個等待事件比較顯著,可能表示在多表連接中,表的連接順序存在問題,可能沒有正確的使用驅(qū)動表;或者可能說明不加選擇地進行索引。                                                                                              在大多數(shù)情況下我們說,通過索引可以更為快速的獲取記錄,所以對于一個編碼規(guī)范、調(diào)整良好的數(shù)據(jù)庫,這個等待很大是很正常的。但是在很多情況下,使用索引并不是最佳的選擇,比如讀取較大表中大量的數(shù)據(jù),全表掃描可能會明顯快于索引掃描,所以在開發(fā)中我們就應(yīng)該注重,對于這樣的查詢應(yīng)該進行避免使用索引掃描。  3. Free Buffer-釋放緩沖區(qū)  這個等待事件表明系統(tǒng)正在等待內(nèi)存中的可用空間,這說明當前Buffer 中已經(jīng)沒有Free 的內(nèi)存空間。假如應(yīng)用設(shè)計良好,SQL 書寫規(guī)范,充分綁定變量,那這種等待可能說明Buffer Cache 設(shè)置的偏小,你可能需要增大DB_BUFFER_CACHE。  Free Buffer 等待可能說明DBWR 的寫出速度不夠,或者磁盤存在嚴重的競爭,可以需要考慮增加檢查點、使用更多的DBWR 進程,或者增加物理磁盤的數(shù)量,分散負載,平衡IO。  4. Buffer Busy-緩沖區(qū)忙
                           該等待事件表示正在等待一個以unshareable方式使用的緩沖區(qū),或者表示當前正在被讀入buffer cache。一般來說Buffer Busy Wait不應(yīng)大于1%。檢查緩沖等待統(tǒng)計部分(或V$WAITSTAT),看一下等待是否位于段頭(Segment Header)。假如是,可以考慮增加自由列表(freelist,對于Oracle8i DMT)或者增加freelist groups(在很多時候這個調(diào)整是立竿見影的,在8.1.6之前,這個freelists參數(shù)不能動態(tài)修改;在8.1.6及以后版本,動態(tài)修改feelists需要設(shè)置COMPATIBLE至少為8.1.6).  假如這一等待位于undo header,可以通過增加回滾段(rollback segment)來解決緩沖區(qū)的問題。假如等待位于undo block上,我們可能需要檢查相關(guān)應(yīng)用,適當減少大規(guī)模的一致性讀取,或者降低一致性讀取(consistent read)的表中的數(shù)據(jù)密度或者增大DB_CACHE_SIZE。  假如等待處于data block,可以考慮將頻繁并發(fā)訪問的表或數(shù)據(jù)移到另一數(shù)據(jù)塊或者進行更大范圍的分布(可以增加pctfree值 ,擴大數(shù)據(jù)分布,減少競爭),以避開這個"熱點"數(shù)據(jù)塊,或者可以考慮增加表中的自由列表或使用本地化治理的表空間(Locally Managed Tablespaces)。  假如等待處于索引塊,應(yīng)該考慮重建索引、分割索引或使用反向鍵索引。為了防止與數(shù)據(jù)塊相關(guān)的緩沖忙等待,也可以使用較小的塊:在這種情況下,單個塊中的記錄就較少,所以這個塊就不是那么"繁忙";或者可以設(shè)置更大的pctfree,使數(shù)據(jù)擴大物理分布,減少記錄間的熱點競爭。  在執(zhí)行DML (insert/update/ delete)時,Oracle向數(shù)據(jù)塊中寫入信息,對于多事務(wù)并發(fā)訪問的數(shù)據(jù)表,關(guān)于ITL的競爭和等待可能出現(xiàn),為了減少這個等待,可以增加initrans,使用多個ITL槽。在Oracle9i 中,引入了一個新概念:ASSM(Segment Space Management Auto)。通過這個新特性O(shè)racle 使用位圖來治理空間使用。  ASSM 結(jié)合LMT 徹底改變了Oracle 的存儲機制,位圖freelist 能夠減輕緩沖區(qū)忙等待(buffer busy wait),這個問題在Oracle9i 以前的版本里曾是一個嚴重的問題。  Oracle 宣稱ASSM 顯著地提高了DML 并發(fā)操作的性能,因為(同一個)位圖的不同部分可以被同時使用,這樣就消除了尋找剩余空間的串行化。根據(jù)Oracle 的測試結(jié)果,使用位圖freelist 會消除所有分段頭部(對資源)的爭奪,還能獲得超快的并發(fā)插入操作。在Oracle9i 之中,Buffer Busy wait 不再常見!  5. latch free-latch 釋放  latch是一種低級排隊機制,用于保護SGA中共享內(nèi)存結(jié)構(gòu)。latch就像是一種快速地被獲取和釋放的內(nèi)存鎖。用于防止共享內(nèi)存結(jié)構(gòu)被多個用戶同時訪問。假如latch不可用,就會記錄latch釋放失敗(latch free miss )。有兩種與閂有關(guān)的類型:  ■ 馬上。  ■ 可以等待。  假如一個進程試圖在馬上模式下獲得閂,而該閂已經(jīng)被另外一個進程所持有,假如該閂不能立可用的話,那么該進程就不會為獲得該閂而等待。它將繼續(xù)執(zhí)行另一個操作。  大多數(shù)latch問題都與以下操作相關(guān):  沒有很好的是用綁定變量(library cache latch)、重作生成問題(redo allocation latch)、緩沖存儲競爭問題(cache buffers LRU chain),以及buffer cache中的存在"熱點"塊(cache buffers chain)。  通常我們說,假如想設(shè)計一個失敗的系統(tǒng),不考慮綁定變量,這一個條件就夠了,對于異構(gòu)性強的系統(tǒng),不使用綁定變量的后果是極其嚴重的。  另外也有一些latch等待與bug有關(guān),應(yīng)當關(guān)注Metalink相關(guān)bug的公布及補丁的發(fā)布。當latch miss ratios大于0.5%時,就應(yīng)當研究這一問題。  Oracle的latch機制是競爭,其處理類似于網(wǎng)絡(luò)里的CSMA/CD,所有用戶進程爭奪latch, 對于愿意等待類型(willing-to-wait)的latch,假如一個進程在第一次嘗試中沒有獲得latch,那么它會等待并且再嘗試一次,假如經(jīng)過_spin_count次爭奪不能獲得latch, 然后該進程轉(zhuǎn)入睡眠狀態(tài),持續(xù)一段指定長度的時間,然后再次醒來,按順序重復(fù)以前的步驟.在8i/9i中默認值是_spin_count=2000。  假如SQL語句不能調(diào)整,在8.1.6版本以上,Oracle提供了一個新的初始化參數(shù): CURSOR_SHARING可以通過設(shè)置CURSOR_SHARING = force 在服務(wù)器端強制綁定變量。設(shè)置該參數(shù)可能會帶來一定的副作用,對于java的程序,有相關(guān)的bug,具體應(yīng)用應(yīng)該關(guān)注Metalink的bug公告。    7. Log Buffer Space-日志緩沖空間                                                                                              當你將日志緩沖(log buffer)產(chǎn)生重做日志的速度比LGWR 的寫出速度快,或者是當日志切換(log switch)太慢時,就會發(fā)生這種等待。這個等待出現(xiàn)時,通常表明redo log buffer 過小,為解決這個問題,可以考慮增大日志文件的大小,或者增加日志緩沖器的大小。
                           另外一個可能的原因是磁盤I/O 存在瓶頸,可以考慮使用寫入速度更快的磁盤。在答應(yīng)的條件下設(shè)置可以考慮使用裸設(shè)備來存放日志文件,提高寫入效率。在一般的系統(tǒng)中,最低的標準是,不要把日志文件和數(shù)據(jù)文件存放在一起,因為通常日志文件只寫不讀,分離存放可以獲得性能提升。  8. Log File Switch-日志文件切換  當這個等待出現(xiàn)時,表示所有的提交(commit)的請求都需要等待"日志文件切換"的完成。  Log file Switch 主要包含兩個子事件:  log file switch (archiving needed)  log file switch (checkpoint incomplete)  log file switch (archiving needed)  這個等待事件出現(xiàn)時通常是因為日志組循環(huán)寫滿以后,第一個日志歸檔尚未完成,出現(xiàn)該等待。出現(xiàn)該等待,可能表示io 存在問題。解決辦法:  可以考慮增大日志文件和增加日志組  移動歸檔文件到快速磁盤  調(diào)整log_archive_max_PRocesses .  log file switch (checkpoint incomplete)-日志切換(檢查點未完成)  當你的日志組都寫完以后,LGWR 試圖寫第一個log file,假如這時數(shù)據(jù)庫沒有完成寫出記錄在第一個log file 中的dirty 塊時(例如第一個檢查點未完成),該等待事件出現(xiàn)。  該等待事件通常表示你的DBWR 寫出速度太慢或者IO 存在問題。  為解決該問題,你可能需要考慮增加額外的DBWR 或者增加你的日志組或日志文件大小。  9. log file sync-日志文件同步  當一個用戶提交或回滾數(shù)據(jù)時,LGWR 將會話期的重做由日志緩沖器寫入到重做日志中。日志文件同步過程必須等待這一過程成功完成。為了減少這種等待事件,可以嘗試一次提交更多的記錄(頻繁的提交會帶來更多的系統(tǒng)開銷)。將重做日志置于較快的磁盤上,或者交替使用不同物理磁盤上的重做日志,以降低歸檔對LGWR的影響。  對于軟RAID,一般來說不要使用RAID 5,RAID5 對于頻繁寫入得系統(tǒng)會帶來較大的性能損失,可以考慮使用文件系統(tǒng)直接輸入/輸出,或者使用裸設(shè)備(raw device),這樣可以獲得寫入的性能提高。  10. log file single write該事件僅與寫日志文件頭塊相關(guān),通常發(fā)生在增加新的組成員和增進序列號時。  頭塊寫單個進行,因為頭塊的部分信息是文件號,每個文件不同。更新日志文件頭這個操作在后臺完成,一般很少出現(xiàn)等待,無需太多關(guān)注。  11. log file parallel write  從log buffer 寫redo 記錄到redo log 文件,主要指常規(guī)寫操作(相對于log file sync)。假如你的Log group 存在多個組成員,當flush log buffer 時,寫操作是并行的,這時候此等待事件可能出現(xiàn)。  盡管這個寫操作并行處理,直到所有I/O 操作完成該寫操作才會完成(假如你的磁盤支持異步IO或者使用IO SLAVE,那么即使只有一個redo log file member,也有可能出現(xiàn)此等待)。  這個參數(shù)和log file sync 時間相比較可以用來衡量log file 的寫入成本。通常稱為同步成本率。  12. control file parallel write-控制文件并行寫  當server 進程更新所有控制文件時,這個事件可能出現(xiàn)。假如等待很短,可以不用考慮。假如等待時間較長,檢查存放控制文件的物理磁盤I/O 是否存在瓶頸。  多個控制文件是完全相同的拷貝,用于鏡像以提高安全性。對于業(yè)務(wù)系統(tǒng),多個控制文件應(yīng)該存放在不同的磁盤上,一般來說三個是足夠的,假如只有兩個物理硬盤,那么兩個控制文件也是可以接受的。在同一個磁盤上保存多個控制文件是不具備實際意義的。減少這個等待,可以考慮如下方法:  減少控制文件的個數(shù)(在確保安全的前提下)  假如系統(tǒng)支持,使用異步IO  轉(zhuǎn)移控制文件到IO 負擔輕的物理磁盤  13. control file sequential read/ control file single write 控制文件連續(xù)讀/控制文件單個寫對單個控制文件I/O 存在問題時,這兩個事件會出現(xiàn)。假如等待比較明顯,檢查單個控制文件,看存放位置是否存在I/O 瓶頸。  14. direct path write-直接路徑寫該等待發(fā)生在,系統(tǒng)等待確認所有未完成的異步I/O 都已寫入磁盤。對于這一寫入等待,我們應(yīng)該找到I/O 操作最為頻繁的數(shù)據(jù)文件(假如有過多的排序操作,很有可能就是臨時文件),分散負載,加快其寫入操作。  假如系統(tǒng)存在過多的磁盤排序,會導(dǎo)致臨時表空間操作頻繁,對于這種情況,可以考慮使用Local治理表空間,分成多個小文件,寫入不同磁盤或者裸設(shè)備。  16. Idle Event-空閑事件  最后我們來看幾個空閑等待事件。一般來說,空閑等待是指系統(tǒng)因為無事可做的等待,或者等待用戶的請求或響應(yīng)等,通常我們可以忽略這些等待事件。空閑事件可以通過stats$idle_event 表查詢得到。  我們看一下系統(tǒng)的主要空閑等待事件,對這些事件大家應(yīng)該有個大致的印象,假如你的Top 5 等待事件中,主要都是這些事件,那么一般來說你的系統(tǒng)是比價清閑的。                          right">(出處:清風(fēng)軟件下載學(xué)院)