latch等待事件彙總

主要的等待事件有以下幾種:

1.l atch free

Latch free等待事件的三個參數:p1-latch的地址;p2-latch編號;p3-請求次數。從oracle10g起,latchfree不再包含所有的latch等待,有些latch等待可能表現爲單獨的等待事件,這個後面有提到一些這樣的等待事件,一般情況下我們還是統稱爲latch free等待事件。

如果我們在v$session_wait中發現有latch free等待事件,就意味着,進程在請求一個willing_to_wait模式的latch,在重試了_spin_count次後還是沒有獲得latch,然後轉入睡眠狀態了。如果latch爭用嚴重,將會由於不斷的spin導致cpu資源緊張,從而增加系統響應時間。


2.latch: shared pool  和 latch: library cache

Shared pool latch主要用來保護共享池的內存結構,當分配或者釋放共享池內存時需要先獲得該latch。例如,爲一個新的sql語句或pl/sql過程、函數、包,觸發器等分配空間(硬解析)時,或者爲換出、清除某些內存塊,以便爲新的對象騰出足夠的空間時,都需要獲取shared pool latch。庫緩存中主要保存遊標,sql語句,執行計劃,分析樹等。這些結構由library cache latch保護。當oracle進程修改、檢查、銷連接(pinning)、鎖定、裝載,或者執行庫緩存中的結構時,都需要先獲得library cache latch。通過查詢v$latch_children可以得知當前實例中的library cache子latch的個數。

wKiom1RkGzzA6588AAG5zh2DItM951.jpg

圖片轉載 https://blog.51cto.com/tiany/1575964


當出現Latch競爭嚴重的時候: 
(1).如果同時出現大量的 Share Pool Latch 和 Library Cache Latch 的話,根據上面的邏輯那說明數 據庫中存在大量的硬解析,這個時候就要查找那些 SQL 沒有綁定變量。 
(2).如果只是出現大量的 Library Cache Latch 的話,那麼可能有兩種情況: 
1) 當持有 Library Cache Latch 查找 Bucket 對應的 Chain 時候,發現存在高 Version 的 SQL,這個時候就要掃描這些對應的子游標,整個過程將一直持有 Latch,導致其他會話獲取不到 Latch 進行操作。

2) 大量的併發請求,而且不能實現 SQL 一次 Parse Call 多次 Execution。


3.

(1).library cache pin ,library cache lock

1).Lock 與 pin 都用於訪問在 library cache 中的對象。Lock 管理不同進程間的併發,pin 則管理緩衝區的一致性。爲了訪問一個對象,進程必須首先鎖定(lock)這個對象的句柄(handle),然後它自己 pin 住對象的內存堆。 
2).Lock 與 pin 請求會一直等待直到獲得爲止,這是一個引起爭用的可能的原因,因爲它沒有 NOWAIT 請求模式。 
3).Oracle 在分析/編譯 Package/Procedure/Function/View 時需要 Library Cache Lock 和 Library Cache Pin。這是爲了確保在分析/編譯期間, 沒有其它人可以對這些對象的定義進行改變,或者刪除、重建這個對象。 
4).當一個 SQL 語句被一個 session 硬解析時,這個 session 需要獲得一個 library cache lock 以便阻止其它 session 去訪問或修改同一個對象。如果這個事件等待很長時間。這表明可能 shared pool 過小或經常發生對象被 flush 出去的情形。這表明數據庫對象被經常修改。 

5).除了硬解析,如果一個 session 要更改被 SQL 語句引用的對象的定義或對其做任何更改,就必須獲得一個 library cache lock 和 library cache pin。需要 Pin 的原因是需要加載數據字典信息到內存中來修改這個對象。


6).如何降低 library cache lock 等待 
   我們首先要確認的是 library cache 的競爭是整個系統層面的還是隻發生在某個或某些 SQL 語句上。這個"library cache lock"是被一個特定的 SQL 持有很長的時間嗎?或者總是在等待某個特定的對象?還是說這個鎖在短時間內被請求的次數很多從而造成的競爭? 
- 如果問題是在整個系統層面發生的,一般來說是由於 shared pool 太小或 SQL 語句不共享造成的。一些解決競爭的方法: 
增大 shared pool 從而減少 reload 的次數,這是因爲 shared pool 過小會造成獲取鎖的時間加長。 
- 如果您發現是某條或某些SQL產生的問題,那麼需要檢查爲什麼它持有鎖的時間會那麼長。 
以下文檔可以用來找到誰在持有鎖以及在哪個對象上: 
Note 122793.1 How to Find which Session is Holding a Particular Library Cache Lock 


7).如何降低 library cache pin 等待 
如果"library cache pin"等待的時間很長那麼很重要的一點就是判斷是隻有一兩個 process 在等待還是有很多的 process 都在等待。 
如果說只是一兩個 process 被另一個 process 阻塞的話,那麼需要檢查持有這個 pin 的 process 爲什麼這麼長時間不釋放。 

如果說等待是大範圍的那麼說明 shared pool 需要優化。


(2).library cache load lock

如果一個對象不在內存中,那麼我們不能對其申請 library cache lock。因此,需要將這個對象加載到內存中。然後,session 嘗試找到數據庫對象的 load lock,以便它能載入這個對象。爲了阻止多進程同時請求加載同一個對象,其它同樣請求的 session 將等待 library cache load lock 因爲這個對象正在被加載到內存中。等待 library cache load lock 是由於對象在內存中是不存在的。 Library cache 中的對象不存在,是由於 shared pool 過小引起的頻繁重新裝載,或太多的硬解析緣於不共享的 SQL。 

解決方法:

- 增加 shared pool(避免 reload). 
- 增加 session cached cursors(避免 cursor 被刷出 shared pool) 
- 設置 cursor_sharing 爲 force(減少硬解析)。---可能改變執行計劃與查詢的性能,所以要作充分的測試。


4.latch: row cache objects

用來保護數據字典緩衝區(row cache的名字主要是因爲其中的信息是按行存儲的,而不是按塊存儲)。進程在裝載、引用或者清除數據字典緩衝區中的對象時必須獲得該latch。在oracle8i之前,這是一個獨立latch。從oracle9i起,由於引入了多個子共享池的新特性,存在多個row cacheobjects子latch。Oracle10g中,該latch也有了一個獨立的等待事件:rowcache objects。


解決方法:

(1).確認SGA 中的share pool 是否還有空閒空間

select POOL,BYTES/1024/1024 FREE_MB from v$sgastat a where a.NAME like  'free%';


(2).查詢ROW CACHE中的GET量及命中率

SELECT  r.cache#,r.parameter name,r.TYPE,r.subordinate#,r.gets,r.GETMISSES,round((1 - r.GETMISSES/r.gets)*100,2) SUC_PCT FROM v$rowcache r where r.gets <>0 ORDER BY 5 desc;


SQL解析到底哪一步訪問了ROWCACHE,哪一步爭用的latch?

這個問題我查詢了好久,我之前以爲只是在語義檢查需要到row cache,其實是在生成執行計劃的時候需要訪問的數據字典次數更多,爭用latch也就更頻繁了,所以這裏纔是最慢的。


5.cache buffers chains

http://blog.itpub.net/15412087/viewspace-2148426/

鄭州婦科醫院:http://jbk.39.net/yiyuanzaixian/sysdfkyy/

6.latch: cache buffers lru chain

一般來講,當進程需要查找可用的緩存空間時,需要訪問lru列表。後臺進程DBWn則會將lruw列表中的乾淨塊移到lru列表中,也會將lru中的髒塊移到lruw列表中。在一個工作集中進行以上的任何操作都需要先獲得cache bufferslru chain latch。

各個數據緩衝區中(包括不同塊大小的緩衝區,keep池和recycle池),每個緩衝區至少需要有一個cache buffers lruchain latch,而一個DBWn進程可能需要多個latch。否則,一個工作集就可能變得很長。在oracle9i和oracle10g中,cache buffers lru chain latch的個數默認是cpu個數的4倍,如果,db_writer_processes大於4,則等於cpu的個數乘以db_writer_processes。可以通過隱含參數_db_block_lru_latches來調節cache buffers lru chain latch的個數。

Cache buffers laru cahin latch的爭用,主要表現爲由於低效的sql語句導致數據緩衝區過度活躍。全表掃描和對某些選擇性較差的大索引的反覆掃描是造成cache buffers laru cahin latch爭用的主要原因。解決辦法是,查找latch free等待事件中關於cache buffers lru chain latch相關的sql語句(在oracle10g中,已經變成一個獨立的cache buffers lru chain等待事件),優化這些sql,降低其物理讀和邏輯讀。


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