latch等待事件彙總

wwjfeng發表於2019-07-18

latch 存在於buffer cache , share pool ,redo buffer中,用於保護記憶體中資料結構不被破壞。


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

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/


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,降低其物理讀和邏輯讀。


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

相關文章