Oracle常見的33個等待事件


  1. Buffer busy waits

        原因:
        當一個會話試圖修改一個數據塊,但這個數據塊正在被另一個會話修改時。
        當一個會話需要讀取一個數據塊,但這個數據塊正在被另一個會話讀取到內存中時。
        備注:數據處理的最小單位是塊

select name,parameter1,parameter2,parameter3 from v$event_name where name='buffer busy waits'; NAME PARAMETER1 PARAMETER2 PARAMETER3 -------------------- ---------- ---------- ---------- buffer busy waits file# block# class#

File#:等待訪問數據塊所在的文件id號。
Blocks:等待訪問的數據塊號。
class#:原因碼
A、如果等待處於字段頭部,應增加自由列表(freelist)的組數,或者增加pctused到pctfree之間的距離。
B、如果等待處於回退段(undo)頭部塊,可以通過增加回滾段(rollback segment)來解決緩沖區的問題;
C、如果等待處於回退段(undo)非頭部塊上,就需要降低驅動一致讀取的表中的數據密度,或者增大DB_CACHE_SIZE;
D、如果等待處於數據塊,可以將數據移到另一數據塊以避開這個"熱"數據塊、增加表中的自由列表或使用LMT表空間;
E、如果等待處於索引塊,應該重建索引、分割索引或使用反向鍵索引。

 問題處理:

select segment_type, owner || '.' || segment_name from dba_extents where file_id = file_id and block_id between block_id and block_id + blocks - 1;

 

2、DB file scattered read
最常見的兩種情況是全表掃描(FTS:Full Table Scan)和索引快速掃描(IFFS:index fast full scan)

3、Direct path read
當發生direct path read等待事件時,意味着磁盤上有大量的臨時數據產生,比如排序,並行執行等操作。或者意味着PGA中空閑空間不足。

4、Direct path write
這個等待事件和direct path read正好相反,是會話將一些數據從PGA中直接寫入到磁盤文件上,而不經過SGA。
這種情況通常發生在:
a.使用臨時表空間排序(內存不足);
b.數據的直接加載(使用append方式加載數據);
c.並行DML操作。

5、Free buffer waits
當一個會話將數據塊從磁盤讀到內存中時,它需要到內存中找到空閑的內存空間來存放這些數據塊,當內存中沒有空閑的空間時,就會產生這個等待;除此之外,還有一種情況就是會話在做一致性讀時,需要構造數據塊在某個時刻的前映像(image),此時需要申請內存來存放這些新構造的數據塊,如果內存中無法找到這樣的內存塊,也會發生這個等待事件。
當數據庫中出現比較嚴重過的free buffer waits等待事件時,可能的原因是:
(1)、data buffer太小,導致空閑空間不夠;
(2)、內存中的臟數據太多,DBWR無法及時將這些臟數據寫到磁盤中以釋放空間。
這個等待事件包含2個參數:
File#:需要讀取的數據塊所在的數據文件的文件號。
Block#:需要讀取的數據塊塊號。

6、Library cache lock
一般可以理解的是alter table或者alter package/procedure會以X模式持有library cache lock,造成阻塞。
但是常見的問題還有以下幾種原因:
1)錯誤的用戶名密碼:
2)正在執行搜集統計信息,這是大家往往會忽略的,一般會看last_ddl_time,卻忽略了last_analyzed,
檢查腳本如下:
比如EMP是遇到library cache lock中的表名:

select owner,object_name,object_type,to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss') from dba_objects where object_name='EMP';
select table_name,to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') from dba_tables where table_name='EMP';

也需要檢查所有dependency的對象,因為oracle對象是相互關聯的,一個對象失效會導致一串失效。

select owner,object_name,object_type,to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss') ddl_time from dba_objects where object_name in
(
select p.name
from sys.obj$ d, sys.dependency$ dep, sys.obj$ p
where d.obj# = dep.d_obj# and p.obj# = dep.p_obj#
start with d.name='EMP'
connect by prior dep.p_obj#=dep.d_obj#)
order by ddl_time desc;

select table_name,to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') from dba_tables where table_name in
(
select p.name
from sys.obj$ d, sys.dependency$ dep, sys.obj$ p
where d.obj# = dep.d_obj# and p.obj# = dep.p_obj#
start with d.name='EMP'
connect by prior dep.p_obj#=dep.d_obj#)
order by last_analyzed desc;

3)錯誤的語句解析(failed parse)

4)bug

7、Library cache pin
這個等待事件和library cache lock一樣是發生在共享池中並發操作引起的事件。通常來講,如果Oracle要對一些PL/SQL或者視圖這樣的對象做重新編譯,需要將這些對象pin到共享池中。
如果此時這個對象被其他的用戶特有,就會產生一個library cache pin的等待。

8、Log buffer space
當log buffer中沒有可用空間來存放新產生的redo log數據時,就會發生log buffer space等待事件。如果數據庫中新產生的redo log的數量大於LGWR寫入到磁盤中的redo log數量,必須等待LGWR完成寫入磁盤的操作,LGWR必須確保redo log寫到磁盤成功之后,才能在redo buffer當中重用這部分信息。
如果數據庫中出現大量的log buffer space等待事件,可以考慮如下辦法:
(1)、增加redo buffer的大小。
(2)、提升磁盤的I/O性能。

9、Log file sequential read
這個等待事件通常發生在對redo log信息進行讀取時,比如在線redo的歸檔操作,ARCH進程需要讀取redo log的信息,由於redo log的信息是順序寫入的,所以在讀取時也是按照順序的方式來讀取的。

10、Log file switch(archiving needed)
在歸檔模式下,這個等待事件發生在在線日志切換(log file switch)時,需要切換的在線日志還沒有被歸檔進程(ARCH)歸檔完畢的時候。當在線日志文件切換到下一個日志時,需要確保下一個日志文件已經被歸檔進程歸檔完畢,否則不允許覆蓋那個在線日志信息(否則會導致歸檔日志信息不完整)。
出現這樣的等待事件通常是由於某種原因導致ARCH進程死掉,比如ARCH進程嘗試向目的地寫入一個歸檔文件,但是沒有成功(介質失效或者其他原因),這時ARCH進程就會死掉。如果發生這種情況,在數據庫的alert log文件中可以找到相關的錯誤信息。

11、Log file switch(checkpoint incomplete)
當一個在線日志切換到下一個在線日志時,必須保證要切換到的在線日志上的記錄信息(比如一些臟數據塊產生的redo log)被寫到磁盤上(checkpoint),這樣做的原因是,如果一個在線日志文件的信息被覆蓋,而依賴這些redo信息做恢復的數據塊尚未被寫到磁盤上(checkpoint) ,此時系統down掉的話,Oracle將沒有辦法進行實例恢復。
在v$log視圖里記錄了在線日志的狀態。通常來說,在線日志有三種狀態。
Active:這個日志上面保護的信息還沒有完成checkpoint。
Inactive:這個日志上面保護的信息已完成checkpoint。
Current:當前的日志。
Oracle在做實例恢復時,會使用狀態為current和active的日志進行實例恢復。
如果系統中出現大量的log file switch(checkpoint incomplete)等待事件,原因可能是日志文件太小或者日志組太少,所以解決的方法是,增加日志文件的大小或者增加日志組的數量。

12、Log file sync
引起log file sync的原因:
1.頻繁提交或者rollback,檢查應用是否有過多的短小的事務,如果有,可以使用批處理來緩解。
2.OS的IO緩慢:解決辦法是將日志文件放裸設備上或綁定在RAID 0或RAID 1+0中,而不是綁定在RAID 5中。
3.過大的日志緩沖區(log_buffer ) 過大的log_buffer,允許LGWR變得懶惰,因為log buffer中的數據量無法達不到_LOG_IO_SIZE,導致更多的重做條目堆積在日志緩沖區中。
當事務提交或者3s醒來時,LGWR才會把所有數據都寫入到redo log file中。 由於數據很多,LGWR要用更多時間等待redo寫完畢。
這種情況,可以調小參數_LOG_IO_SIZE參數,其默認值是LOG_BUFFER的1/3或1MB,取兩者之中較小的值。
換句話說,你可以具有較大的日志緩沖區,但較小的_LOG_IO_SIZE將增加后台寫入次數,從而減少log file sync的等待時間。
4.CPU負載高。詳見下面的描述。
5.RAC私有網絡性能差,導致LMS同步commit SCN慢

判斷:
1.如果log file sync的等待時間很高,而log file parallel write的等待時間並不高,這意味着log file sync的原因並不是緩慢的日志I/O,而是應用程序過多的提交造成。
當log file sync的等待時間和 log file parallel write等待時間基本相同,說明是IO問題造成的log file sync等待事件。
2.Lgwr trace file(10.2.0.4開始),大於500ms會寫入
trace文件中如果有Warning: log write time 1000ms, size 2KB,很有可能IO慢。3.分析CPU資源使用情況的工具,CPU過於繁忙,lgwr無法及時獲取CPU調度,出現log file sync。
vmstat,關注r是否大於CPU核數,大於說明cpu繁忙。
log file sync=CPU+幾個latch+log file parallel write(此處latch申請一般不是瓶頸)
--如果log file sync遠大於log file parallel write的等待時間,只會為以下三種情況
1、CPU資源緊張
2、LGWR在申請latch資源時遇到競爭(IMU未使用,RAC環境下不適用)
3、同時提交的進程太多

解決辦法:
1.如果確實是因為頻繁提交造成的log file sync,那么減少commit,批量提交。
2.如果確實是因為io引起的,那么解決辦法是將日志文件放裸設備上或綁定在RAID 1+0中,而不是放在在RAID 5中(切記,redo log file一定不要放在SSD上!!!)。
3.確保CPU資源充足。CPU資源不足,LGWR通知user session后,user session無法及時獲得CPU調度,不能正常工作。
4.是否有些表可以使用nologging,會減少redo產生量5.檢查redo log file足夠大,確保redo log file每15到20分鍾切換一次。

13、cursor: pin S wait on X
cursor: pin S,cursor: pin X,cursor: pin S wait on X這三個等待事件,實際上就是替代了cursor的library cache pin,pin S代表執行(share pin),pin X代表解析(exclusive pin),
pin S wait on X代表執行正在等待解析操作。
這里需要強調一下,它們只是替換了訪問cursor的library cache pin,而對於訪問procedure這種實體對象,依然是傳統的library cache pin。
cursor: pin S wait on X,這個等待事件主要是由硬解析引起的
--硬解析,軟解析,軟軟解析在共享池中的等待事件
1、硬解析:latch: shared pool,硬解析需要所有類型的mutex,包括library cache: mutex,cursor: pin,HASH Table,cursor Parent
2、軟解析:library cache: mutex,cursor: pin,HASH Table,cursor Parent
3、軟軟解析(將子游標堆6的信息,緩存在PGA中。子游標堆6:保存執行計划信息):兩次cursor: pin S和一次library cache: mutex X(如果使用綁定變量或且使用靜態游標,會導致一次library cache: mutex X)
4、sql版本過多:library cache和HASH Table類型等待
總結:如果只有cursor: pin類型和library cache: mutex型競爭激烈,是軟軟解析問題;如果還有其他類mutex型等待,則是軟解析導致。如果再有shared pool latch競爭激烈,一定是硬解析過多,由於大量進程同時請求從共享池中分配內存導致;
版本過多的硬解析:library cache lock和HASH Table類型等待同時出現,如果只有HASH Table類型等待而沒有library cache lock,則是版本過多的父游標有很多並發的軟解析。

硬解析導致異常等待處理:使用綁定變量(應用層面),cursor sharing=true 禁用ACS(adaptive cursor sharing),配置充足的shared pool v$sqlarea sql_text列中相似的sql很多,說明未使用綁定變量
軟解析爭用處理:調整session cached cursors參數,使軟解析變為軟軟解析
軟軟解析導致爭用處理:cursor pin:s ,使用提示符/**/改變sql hash值,將一條SQL變為多條減少爭用;應用層緩存游標,實現一次解析,多次執行


--導致oracle high version count(高版本游標)
原因:1、owner不同 2、表統計信息發生變化 3、系統環境統計信息發生變化
SELECT * FROM v$sql_shared_cursor e WHERE e.SQL_ID = 'a4tjn5xjzx2mt'
綁定變量長度變大會導致BIND_MISMATCH

14、latch:cache buffers chains
一般產生CACHE BUFFERS CHAINS的原因有幾個方面:

1、buffer cache太少(也說明SQL語句效率低,較多的邏輯讀意味着較多的latch get操作,從而增加了鎖存器爭用。多個進程同時掃描大范圍的索引或表時,可能廣泛地發生cache buffers chains 鎖存器爭用);

2、熱塊掙用。(從oracle9i開始,對latch:cache buffer chains支持只讀共享訪問,這可以減少部分爭用,但並不能完全消除爭用。)
當多個會話重復訪問一個或多個由同一個子cache buffers chains鎖存器保護的塊時,就會產生熱塊掙用。當多個會話爭用cache buffers chains鎖存器時,找出是否有熱塊的最好的方法是檢查latch free等待事件的P1RAW參數值。
判斷熱塊掙用的另一種方法是從 v$session_wait 視圖獲得鎖存器地址后進行比較。v$session_wait的P1RAW就相當於子鎖存器地址,若從 v$session_wait 視圖獲得的鎖存器地址過多重復出現,就意味着對相應鎖存器發生次數偏多,此時可解釋為熱快引起的爭用。如果會話正在相同的鎖存器地址上等待,就是熱塊。

SQL> select sid,p1raw,p2,p3,seconds_in_wait,wait_time,state from v$session_wait where event='latch: cache buffers chains' order by 3,2;

使用P1RAW=00000300DA316800為例子進行關聯熱快對象。

SQL> select a.hladdr,a.file#,a.dbablk,a.tch,a.obj,b.object_name from x$bh a, dba_objects b
where (a.obj = b.object_id or a.obj = b.data_object_id) and a.hladdr = '00000300DA316800'
union select hladdr,file#,dbablk,tch,obj,null from x$bh
where obj in (select obj from x$bh where hladdr = '00000300DA316800' minus select object_id from dba_objects minus select data_object_id from dba_objects) and hladdr = '00000300DA316800' order by 4;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM