等待事件分析

張衝andy發表於2016-12-29
在Oracle 10g中的等待事件有872個,11g中等待事件1116個。 我們可以透過v$event_name 檢視來檢視等待事件的相關資訊。


1.1 檢視v$event_name檢視的欄位結構:


SQL> desc v$event_name
 Name
 ---------------------------
 EVENT#
 EVENT_ID
 NAME
 PARAMETER1
 PARAMETER2
 PARAMETER3
 WAIT_CLASS_ID
 WAIT_CLASS#
 WAIT_CLASS


1.2  檢視等待事件總數:
SQL> select count(*) from v$event_name;


  COUNT(*)
----------
      1118


1.3  檢視等待事件分類情況:


SQL>   SELECT   wait_class#,
  2             wait_class_id,
  3             wait_class,
  4             COUNT ( * ) AS "count"
  5      FROM   v$event_name
  6  GROUP BY   wait_class#, wait_class_id, wait_class
  7  ORDER BY   wait_class#;


WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS                                                            count
----------- ------------- ---------------------------------------------------------------- ----------
          0    1893977003 Other                                                                   719
          1    4217450380 Application                                                              17
          2    3290255840 Configuration                                                            24
          3    4166625743 Administrative                                                           54
          4    3875070507 Concurrency                                                              32
          5    3386400367 Commit                                                                    2
          6    2723168908 Idle                                                                     94
          7    2000153315 Network                                                                  35
          8    1740759767 User I/O                                                                 45
          9    4108307767 System I/O                                                               30
         10    2396326234 Scheduler                                                                 7


WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS                                                            count
----------- ------------- ---------------------------------------------------------------- ----------
         11    3871361733 Cluster                                                                  50
         12     644977587 Queueing                                                                  9


13 rows selected.


1.4  相關的幾個檢視:


V$SQLTEXT:  當資料庫出現瓶頸時,通常可以從V$SESSION_WAIT找到那些正在等待資源的SESSION,透過SESSION的SID,聯合V$SESSION和V$SQLTEXT檢視就可以捕獲這些SESSION正在執行的SQL語句。     (SQL層等待分析)
V$SESSION:  代表資料庫活動的開始,視為源起。
V$SESSION_WAIT:  檢視用以實時記錄活動SESSION的等待情況,是當前資訊。  (會話層等待分析)
如: select event,total_waits from v$session_event where sid=### order by total_waits desc;
V$SYSTEM_EVENT 由於V$SESSION記錄的是動態資訊,和SESSION的生命週期相關,而並不記錄歷史資訊,所以ORACLE提供檢視V$SYSTEM_EVENT來記錄資料庫自啟動以來所有等待事件的彙總資訊。透過這個檢視,使用者可以迅速獲得資料庫執行的總體概況。  (系統層等待分析)
如:  select event,total_waits from v$system_event order by total_waits desc;
V$SESSION_WAIT_HISTORY:  是對V$SESSION_WAIT的簡單增強,記錄活動SESSION的最近10次等待。
V$ACTIVE_SESSION_HISTORY: 是ASH的核心,用以記錄活動SESSION的歷史等待資訊,每秒取樣一次,這部分內容記錄在記憶體中,期望值是記錄一個小時的內容。
WRH#_ACTIVE_SESSION_HISTORY : 是V$ACTIVE_SESSION_HISTORY在AWR的儲存地。
V$ACTIVE_SESSION_HISTORY: 中的資訊會被定期(每小時一次)的重新整理到負載庫中,並預設保留一個星期用於分析。
DBA_HIST_ACTIVE_SESS_HISTORY: 檢視是WRH#_ACTIVE_SESSION_HISTORY檢視和其他幾個檢視的聯合展現,通常透過這個檢視進行歷史資料的訪問。


1.5 常見的等待事件


1.5.1   db file scattered read


產生原因:
當PGA中無所需資料,資料塊以multiblock read的行式被讀取到SGA中時。如:FTS(full table scan),IFFS(index fast full scan)
解決對策:
無需解決、考慮索引、考慮並行


1.5.2   DB File Sequential Read  (單塊讀等待)


背景知識:
這裡的sequential指的是將資料塊讀入到相連的記憶體空間中(contiguous memory space),而不是指所讀取的資料塊是連續的。
產生原因:
a:  最為常見的是執行計劃中包含了INDEX FULL SCAN/UNIQUE SCAN,此時出現”db file sequential read”等待是預料之中的,一般不需要我們去特別關注


b:  當執行計劃包含了INDEX RANGE SCAN-(“TABLE ACCESS BY INDEX ROWID”/”DELETE”/”UPDATE”), 服務程式將按照”訪問索引->找到rowid->訪問rowid指定的表資料塊並執行必要的操作”順序訪問index和table,每次物理 讀取都會進入”db file sequential read”等待,且每次讀取的都是一個資料塊;這種情況下clustering_factor將發揮其作用,需要我們特別去關注,本例中提及的解決方法對 這種情景也有效


c:  Extent boundary,假設一個Extent區間中有33個資料塊,而一次”db file scattered read”多塊讀所讀取的塊數為8,那麼在讀取這個區間時經過4次多塊讀取後,還剩下一個資料塊,但是請記住多塊讀scattered read是不能跨越一個區間的(span an extent),此時就會單塊讀取並出現”db file sequential read”。這是一種正常現象,一般不需要額外關注


d:  假設某個區間內有8個資料塊,它們可以是塊a,b,c,d,e,f,g,h,恰好當前系統中除了d塊外的其他資料塊都已經被快取在buffer cache中了,而這時候恰好要訪問這個區間中的資料,那麼此時就會單塊讀取d這個資料塊,並出現”db file sequential read”等待。注意這種情況不僅於表,也可能發生在索引上。這是一種正常現象,一般不需要額外關注


e:  chained/migrated rows即鏈式或遷移行,這裡我們不介紹鏈式行的形成原因,chained/migrated rows會造成服務程式在fetch一行記錄時需要額外地單塊讀取,從而出現”db file sequential read”。這種現象需要我們特別去關注,因為大量的鏈式/遷移行將導致如FULL SCAN等操作極度惡化(以往的經驗是一張本來全表掃描只需要30分鐘的表,在出現大量鏈式行後,全表掃描需要數個小時),同時也會對其他操作造成不那麼 明顯的效能影響。可以透過監控v$sysstat檢視中的”table fetch continued row”操作統計來了解系統中鏈式/遷移行訪問的情況,還可以透過DBA_TBALES檢視中的CHAIN_CNT來了解表上的鏈式/遷移行情況,當然這 要求定期收集表上的統計資訊;如果沒有定期收集的習慣,那麼可以配合@?/rdbms/admin/utlchain指令碼和analyze table list chained rows 命令來獲取必要的鏈式行資訊


f:  建立Index entry,顯然當對錶上執行INSERT操作插入資料時,雖然在執行計劃中你看不到過多的細節,但實際上我們需要利用索引來快速驗證表上的某些約束是否 合理,還需要在索引的葉子塊中插入相關的記錄,此時也可能出現”db file sequential read”等待事件,當然這還和具體的插入的方式有關係。這是一種正常現象,一般不需要額外關注


1.5.3  Direct Path Read


產生原因:
資料被直接讀取到PGA記憶體中時,發生的等待。如:排序資料由於記憶體不足,被寫到磁碟上(temp表空間資料檔案)
,然後重新讀取時。
解決辦法:
無需解決、增大記憶體排序區(PGA)、調整操作的並行度、改善磁碟I/O、


1.5.4  Direct Path  write


產生原因:
資料從PGA記憶體中直接寫到磁碟上,發生的等待。 如:排序資料由於記憶體不足,被寫到磁碟上(temp表空間資料檔案)




1.5.5  Log File Sync


產生原因:
使用者commit(rollback)時,lgwr需要將log buffer的資料寫到log file上面,發生的等待。
解決本法:
減少commit的頻率(錯誤的頻繁提交)、提高I/O效能、增加lgwr程式個數


1.5.6   buffer busy waits  (熱快)


產生原因:
在SGA中讀取或修改緩衝區的會話必須首先獲取cache buffers chains鎖存器,並且遍歷這個緩衝區鏈,直到他發現必需的緩衝區頭。然後,他必須以共享模式或獨佔模式獲取一個緩衝區鎖或緩衝區頭上的pin,這取決於他計劃的操作。一旦緩衝區頭被釘住,會話就釋放cache buffers chains鎖存器,並在緩衝區自身上執行計劃的操作。如果無法獲取一個pin,會話就在buffer busy waits等待事件上等待。這種等待時間不會應用於在會話的私有PGA中執行的讀取或寫入操作。
解決辦法:
1、出現此情況通常可能透過幾種方式調整:增大data  buffer;
2、增加freelist,減小pctused;怎樣的目的是將一個block上可以使用的空間減少,這樣的話:一個block上的資料存放的較少,可以提高應用的訪問併發率,減少hot block的產生;
3、增加回滾段數目,增大initrans,考慮使用LMT, 確認是不是由於熱點塊造成(如果是可以用反轉索引,或者用更小塊大小);
3、可以建立block較小的表空間,見熱點物件移動到此表空間上去;
4、最佳化應用,最佳化索引,提高索引的命中率;
◎ Oracle會話正在等待釘住一個緩衝區。必須在讀取或修改緩衝區前將它釘住。在任何時刻只有一個程式可以釘住一個緩衝區。
◎ buffer busy waits表明讀/讀、讀/寫、寫/寫爭用。
◎ 採取的適當措施取決於P3引數中的原因碼。
A、如果等待處於欄位頭部,應增加自由列表(freelist)的組數,或者增加pctused到pctfree之間的距離。
B、如果等待處於回退段(undo)頭部塊,可以透過增加回滾段(rollback segment)來解決緩衝區的問題;
C、如果等待處於回退段(undo)非頭部塊上,就需要降低驅動一致讀取的表中的資料密度,或者增大DB_CACHE_SIZE;
D、如果等待處於資料塊,可以將資料移到另一資料塊以避開這個"熱"資料塊、增加表中的自由列表或使用LMT表空間;
E、如果等待處於索引塊,應該重建索引、分割索引或使用反向鍵索引。


1.5.7    free buffer waits


產生原因:
server process無法找一個可用的記憶體空間。
(系統I/O成為瓶頸(或者效能不夠)、等待資源 latch爭用、SGA太小、SGA太大,dbwr無法快速的把髒資料刷到磁碟上)
解決辦法:
最佳化I/O、增加多個dbwr 程式、增大SGA





個人總結與網路總結
部分參考:

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

相關文章