ORACLE 等待事件--《深入淺出ORACLE第八章》

等待事件的源起

等待事件的概念大概是從ORACLE 7.0.12中引入的,大致有100個等待事件。在ORACLE 8.0中這個數目增大到了大約150個,在ORACLE 8I中大約有220個事件,在ORACLE 9IR2中大約有400個等待事件,而在最近ORACLE 10GR2中,大約有874個等待事件。

雖然不同版本和組件安裝可能會有不同數目的等待事件,但是這些等待事件都可以通過查詢V$EVENT_NAME視圖獲得:

SQL> select * from v$version;

 

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE    10.2.0.1.0      Production

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 – Production

SQL> select count(*) from v$event_name;

 

  COUNT(*)

----------

       872

 

ORACLE的等待事件,主要可以分爲兩類,即空閒(IDLE)等待事件非空閒(NON-IDLE)等待事件。空閒等待事件指ORACLE正等待某種工作,在診斷和優化數據庫的時候,不用過多注意這部分事件。非空閒等待事件專門針對ORACLE的活動,指數據庫任務或應用運行過程中發生的等待,這些等待事件是在調整數據庫的時候需要關注與研究的。

下面來看一下ORACLE 10GR2中主要分類及各類等待事件的個數:

SQL> select wait_class#,wait_class_id,wait_class,count(*) as "count"

  2  from v$event_name

  3  group by wait_class#,wait_class_id,wait_class

  4  order by wait_class#;

WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS                          count

----------- ------------- ------------------------------ ----------

          0    1893977003 Other                                 588

          1    4217450380 Application                            12

          2    3290255840 Configuration                          23

          3    4166625743 Administrative                         46

          4    3875070507 Concurrency                            24

          5    3386400367 Commit                                  1

          6    2723168908 Idle                                   62

          7    2000153315 Network                                26

          8    1740759767 User I/O                               17

          9    4108307767 System I/O                             24

         10    2396326234 Scheduler                               2

 

WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS                          count

----------- ------------- ------------------------------ ----------

         11    3871361733 Cluster                                47

 

12 rows selected.

 

幾個視圖的總結

V$SESSION 代表數據庫活動的開始,視爲源起。

V$SESSION_WAIT 視圖用以實時記錄活動SESSION的等待情況,是當前信息。

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視圖和其他幾個視圖的聯合展現,通常通過這個視圖進行歷史數據的訪問。

 

V$SYSTEM_EVENT 由於V$SESSION記錄的是動態信息,和SESSION的生命週期相關,而並不記錄歷史信息,所以ORACLE提供視圖V$SYSTEM_EVENT來記錄數據庫自啓動以來所有等待事件的彙總信息。通過這個視圖,用戶可以迅速獲得數據庫運行的總體概況。

V$SQLTEXT 當數據庫出現瓶頸時,通常可以從V$SESSION_WAIT找到那些正在等待資源的SESSION,通過SESSION的SID,聯合V$SESSION和V$SQLTEXT視圖就可以捕獲這些SESSION正在執行的SQL語句。

 

重要等待事件

Db file sequential read(數據文件順序讀取)

Db file sequential read是個非常常見的I/O相關的等待事件,通常顯示與單個數據塊相關的讀取操作,在大多數情況下,讀取一個索引塊或者通過索引讀取一個數據塊時,都會記錄這個等待。

這個等待事件有3個參數P1、P2、P3,其中P1代表Oracle要讀取的文件的絕對文件號,P2代表Oracle從這個文件中開始讀取的起始數據塊塊號,P3代表讀取的Block數量,通常這個值爲1,表明是單個Block被讀取。

SQL> select name,parameter1,parameter2,parameter3

 2 from v$event_name where name='db file sequential read';

NAME

----------------------------------------------------------------

PARAMETER1

----------------------------------------------------------------

PARAMETER2

----------------------------------------------------------------

PARAMETER3

----------------------------------------------------------------

db file sequential read

file#

block#

blocks

 

如果這個等待事件比較顯著,可能表示在多表連接中,表的連接順序存在問題,可能沒有正確的使用驅動表;或者可能索引的使用存在問題,並非索引總是最好的選擇。

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

從Oracle 9iR2開始,Oracle引入了段級統計信息收集的新特性,收集的統計信息共有11類:

Select * from v$segstat_name;

在Oracle 10gR2中,這類統計信息增加爲15個。

對於CBO模式下的數據庫,應當及時收集統計信息,使SQL可以選擇正確的執行計劃,避免因爲統計信息陳舊而導致的執行錯誤等。

 

Db file scattered read(數據文件離散讀取)

SQL> select * from v$event_name where name='db file scattered read';

   EVENT# NAME

---------- ----------------------------------------------------------------

PARAMETER1

----------------------------------------------------------------

PARAMETER2

----------------------------------------------------------------

PARAMETER3

----------------------------------------------------------------

      188 db file scattered read

file#

block#

blocks

從V$EVENT_NAME視圖可以看到,該事件有3個參數,分別代表文件號、起始數據塊號、數據塊的數量。

起始數據塊號加上數據塊的數量,這意味着Oracle session正在等待多塊連續讀操作的完成。這個操作可能與全表掃描(Full table scan)或者快速全索引掃描(Index Fast Full Scan)的連續讀取相關。根據經驗,通常大量的db file scattered read等待可能意味着應用問題或者索引缺失。

在實際環境的診斷過程中,可以通過v$session_wait視圖發現session的等待,再結合其他視圖找到存在問題的SQL等根本原因,從而從根本上解決問題。當這個等待事件比較顯著時,也可結合v$session_longops動態性能視圖來進行診斷,該視圖記錄了長時間(運行時間超過6秒的)運行的事務。

從Oracle 9i開始,Oracle新增加了一個視圖V$SQL_PLAN用於記錄當前系統Library Cache中SQL語句的執行計劃,可以通過這個視圖找到存在問題的SQL語句。

通過V$SQL_PLAN視圖,可以獲得大量有用的信息:

獲得全表掃描的對象

Select distinct object_name,object_owner from v$sql_plan p

Where p.operation=’TABLE ACCESS’and p.options=’FULL’ and object_owner=’SCOTT’;

獲得全索引掃描的對象

Select distinct object_name,object_owner from v$sql_plan p

Where p.operation=’INDEX’ and p.options=’FULL SCAN’ and object_owner=’SCOTT’;

通過V$SQL_PLAN和V$SQLTEXT聯合,獲得全表掃描的SQL語句

Select sql_text from v$sqltext t,v$sql_plan p

Where t.hash_value=p.hash_value

And p.operation=’TABLE ACCESS’

And p.options=’FULL’

Order by p.hash_value,t.piece;

 

Direct path read/write(直接路徑讀/寫)

直接路徑讀通常發生在Oracle直接讀取數據到PGA時,這個讀取不需要經過SGA。直接路徑讀等待事件的3個參數分別是:file#(指絕對文件號)、first block#和block數量。

這類讀取通常在以下情況被使用:

  • 磁盤排序IO操作
  • 並行查詢從屬進程
  • 預讀操作

最常見的是第一種情況。在DSS系統中,存在大量的Direct path read是很正常的,但是在OLTP系統中,通常顯著的直接路徑讀都意味着系統應用存在問題,從而導致大量的磁盤排序讀取操作。

直接路徑寫通常發生在Oracle直接從PGA寫數據到數據文件或臨時文件,這個寫操作可以繞過SGA。直接路徑寫等待事件的3個參數分別是:file#(指絕對文件號)、first block#和block數量。

這類讀取通常在以下情況被使用:

  • 直接路徑加載
  • 並行DML操作
  • 磁盤排序
  • 對未緩存的“LOB”段的寫入,隨後會記錄爲direct path write(lob)等待

最常見的直接路徑寫,多數因爲磁盤排序導致。對於這一寫入等待,應該找到I/O操作最爲頻繁的數據文件(如果有過多的排序操作,很有可能就是臨時文件),分散負載,加快其寫入操作。

如果系統存在過多的磁盤排序,會導致臨時表空間操作頻繁,對於這種情況,可以考慮爲不同用戶分配不同的臨時表空間,使用多個臨時文件,寫入不同磁盤或者裸設備,從而降低競爭提高性能。

 

日誌文件相關等待

SQL> select name from v$event_name where name like '%log%';

NAME

----------------------------------------------------------------

log switch/archive

log file sequential read

log file single write

log file parallel write

log buffer space

log file switch (checkpoint incomplete)

log file switch (archiving needed)

log file switch (clearing log file)

switch logfile command

log file switch completion

log file sync

STREAMS capture process waiting for archive log

 

已選擇12行。

 

Log File Switch(日誌文件切換)

Log File Switch當日志文件發生切換時出現,在數據庫進行日誌切換時,LGWR需要關閉當前日誌組,切換並打開下一個日誌組,在這個切換過程中,數據庫的所有DML操作都處於停頓狀態,直至這個切換完成。

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

log file switch(achiving needed),即日誌切換(需要歸檔)

這個等待事件出現時通常是因爲日誌組循環寫滿以後,在需要覆蓋先前日誌時,發現日誌歸檔尚未完成,出現該等待。由於Redo不能寫出,該等待出現時,數據庫將陷於停頓狀態。

出現該等待,可能表示I/O存在問題、歸檔進程寫出緩慢,也有可能是日誌組設置不合理等原因導致。針對不同原因,可以考慮採用的解決方法有:

  • 可以考慮增大日誌文件和增加日誌組;
  • 移動歸檔文件到快速磁盤;
  • 調整log_archive_max_processes參數等;

log file switch(checkpoint incomplete),即日誌切換(檢查電未完成)

當所有的日誌組都寫滿之後。LGWR試圖覆蓋某個日誌文件,如果這時數據庫沒有完成寫出由這個日誌文件所保護的髒數據時(檢查點未完成),該等待事件出現。該等待出現時,數據庫同樣將陷於停頓狀態。

該等待事件通常表示DBWR寫出速度太慢或者I/O存在問題。爲解決該問題,可能需要考慮增加額外的DBWR或者增加日誌組或日誌文件大小。

 

Log File Sync(日誌文件同步)

當一個用戶提交或回滾數據時,LGWR將會話期的重做由日誌緩衝區寫入到重做日誌中,LGWR完成任務以後會通知用戶進程。日誌文件同步過程(Log File Sync)必須等待這一過程成功完成。對於回滾操作,該事件記錄從用戶發出Rollback命令道回滾完成的時間。

如果該等待過多,可能說明LGWR的寫出效率低下,或者系統提交過於頻繁。針對該問題,可以通過log file parallel write等待事件或User Commits、User Rollback等統計信息來觀察提交或回滾次數。

可能的解決方案主要有:

提高LGWR性能,儘量使用快速磁盤,不要把redo log file存放在RAID5的磁盤上;

使用批量提交;

適當使用NOLOGGING/UNRECOVERABLE等選項

 

Log File Single Write

該事件僅與寫日誌文件頭塊相關,通常發生在增加新的組成員和增進序列號(Log switch)時。頭塊寫單個進行,因爲頭塊的部分信息是文件號,每個文件不同。

 

Log File Parallel Write

從Log Buffer寫Redo記錄到日誌文件,主要指常規寫操作(相對於Log File Sync)。如果Log Group存在多個組成員,當Flush Log Buffer時,寫操作是並行的,這時候此等待事件可能出現。

 

Log Buffer Space(日誌緩衝空間)

當數據庫產生日誌的速度比LGWR的寫出速度快,或者當日志切換太慢時,就會發生這種等待。這個等待出現時,通常表明Redo log buffer過小,爲解決這個問題,可以考慮增大日誌文件的大小或者增加日誌緩衝器的大小。

另一個可能的原因是磁盤I/O存在瓶頸,可以考慮使用寫入速度更快的磁盤。在允許的條件下設置,可以考慮使用裸設備來存放日誌文件,提高寫入效率。在一般的系統中,最低的標準是,不要把日誌文件和數據文件存放在一起,因爲通常日誌文件只寫不讀,分離存放可以獲得性能提升,儘量使用RAID10而不是RAID5磁盤來存儲日誌文件。

 

Enqueue(隊列等待)

Enqueue是一種保護共享資源的鎖定機制。該鎖定機制保護共享資源,以避免因併發操作而損壞數據,比如通過鎖定保護一行記錄,避免多個用戶同時更新。Enqueue採用排隊機制,即FIFO(先進先出)來控制資源的使用。

Enqueue是一組鎖定事件的集合,如果數據庫中這個等待事件比較顯著,還需要進一步追蹤是哪一個類別的鎖定引發了數據庫等待。

SQL> select name,wait_class

  2  from v$event_name where name like '%enq%'

  3  and rownum<11;             --這裏記錄很多 只去取出了前10條而已

 

NAME                           WAIT_CLASS

------------------------------ ------------------------------

enq: PW - flush prewarm buffer Application

s

 

enq: RO - contention           Application

enq: RO - fast object reuse    Application

enq: KO - fast object checkpoi Application

nt

 

enq: TM - contention           Application

enq: ST - contention           Configuration

enq: HW - contention           Configuration

 

NAME                           WAIT_CLASS

------------------------------ ------------------------------

enq: SS - contention           Configuration

enq: TX - row lock contention  Application

enq: TX - allocate ITL entry   Configuration

 

10 rows selected.

 

Latch Free(閂鎖釋放)

Latch Free通常被稱爲閂鎖釋放,這個名稱常常引起誤解,實際上應該在前面加上一個”等待(WAIT)”,當數據庫出現這個等待時,說明有進程正在等待某個Latch被釋放,也就是Waiting Latch Free。

Latch是一種低級排隊(串行)機制,用於保護SGA中共享內存結構。Latch就像是一種快速的被獲取和釋放的內存鎖,用於防止共享內存結構被多個用戶同時訪問。



文章轉載地址:http://blog.csdn.net/wanghai__/article/details/4912504

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章