轉:latch wait events 說明分析

mengzhaoliang發表於2009-03-24


latch是用於保護記憶體(系統全域性區,SGA)中的共享記憶體結構的互斥機制。Latch就像是記憶體上的鎖,可以由一個程式非常快速地啟用和釋放,用於防止對一個共享記憶體結構進行並行訪問。如果latch不可用,那麼將記錄latch釋放失敗。絕大多數latch問題都與沒有使用繫結變數(library-cache latch(庫快取latch))、重做日誌生成問題(redo-allocation latch(重做日誌的分配latch ))、快取競爭問題(cache-buffers LRU-chain latch(快取的最近最少使用鏈latch))及快取中的熱塊(cache-buffers chain latch(快取鏈latch))有關。(有些latch等待是由於產品bug引起的,如果是這種情況,請檢視Oracle SupportMetaLink站點。)當latch失敗率大於0.5%時,就應該對這一問題進行研究。(下面你將瞭解到如何確定latch失敗率。)

latch有兩種型別:願意等待的(willing-to-waitlatch和不願意等待的(not-willing-to-waitlatch,第一種願意等待一個latch直到它可用,第二種不願意等待。

當一個願意等待的latch(例如,library cache latch)試圖獲得一個latch但沒有latch可用時,它將進行自旋(等待),然後再次請求latch。該latch將繼續重複這一過程,直到自旋(spin)次數達到沒有正式文件的初始化引數_SPIN_COUNT。如果它在自旋次數達到_SPIN_COUNT之後,還沒有得到latch,它將進入睡眠,然後在一釐秒(百分之一秒)之後甦醒。在再次開始之前,該latch將第二次進行這個過程,只不過自旋次數達到_SPIN_COUNT之後睡眠兩倍長的時間(即二釐秒)。這個過程之後,它每次的睡眠時間將成倍增加,直到獲得latch為止。該latch每次睡眠時,都建立一個latch睡眠等待。

而一些latch卻不願意等待。這種型別的latch(例如,redo-copy latch(重做日誌的複製latch))不等待,而是立即再次嘗試獲取latch

檢視兩種latch的相關資訊

你可以在V$LATCH檢視的immediate_gets immediate_misses列裡檢視願意等待的latch和不願意等待的latch的相關資訊,你也可以在Statspack報告的latch部分檢視這些資訊。

透過查詢V$LATCH 試圖或檢視Statspack報告的latch活動部分,你能夠看到有多少程式必須等待(latch失敗)或睡眠(latch睡眠)及他們必須睡眠的次數。V$LATCHHOLDERV$LATCHNAMEV$LATCH_CHILDREN對研究latch問題也是有幫助的。

顯示了Statspack報告中latch活動部分的部分清單,Statspack報告描述了latch名稱、latch失敗(Pct Get Miss列)和latch睡眠(Avg Slps/Miss列)等情況。這一特殊報告簡要地說明了庫快取問題。

當你檢查Statspack報告的等待事件(Wait Events)部分時,要記住latch的命中率應該接近99%,失敗率不應該超過1%。讓我們來檢查一下Statspack報告的這一部分中的行,如所示。

Latch釋放:latch釋放是等待事件部分的一個問題時,需要調查Statspack報告的latch部分存在的問題。該部分將幫助你找出哪些latch是問題所在,例如,睡眠的latch(不能獲得latch,並睡眠直到下一次嘗試)或自旋的latch(根據自旋次數等待並進行再次嘗試)

row cache objects(行快取物件)latchrow cache objects latch 爭用通常意味著在資料字典裡存在競爭。這一問題也可能是對依賴於公共同義詞的SQL語句解析過度的徵兆。一般來說,增大共享池可以解決這一latch問題。你通常可以在它成為一個問題之前,增大共享池以解決library cache latch問題。 cache buffers chains latchcache-buffers chains latch 用於掃描資料庫快取的系統全域性區(SGA)快取。該快取中的熱塊(經常被訪問的塊)引起了cache-buffers chains latch 問題。熱塊也可能是沒有對SQL語句進行調優的徵兆。熱記錄產生了會導致本塊自身及同一鏈中其他任何塊中的其他記錄問題的熱塊。為了找到該熱塊,請查詢V$LATCH_CHILDREN獲取地址,並將其加入到V$BH中,以識別由該latch所保護的塊(這樣做,將顯示受該熱塊影響的所有塊)。你可以根據從查詢V$BH中找到的file#dbablk來查詢DBA_EXTENTS,從而識別這一物件。使用反向鍵(reverse-key)索引(如果該熱塊在一個索引上)將把其他記錄移至其他塊上,以便使它們不被鏈中的該熱塊鎖定。

如果該熱塊是索引根塊(index root block),反向鍵索引將不能起到作用。將設定為恰好比快取塊數(DB_CACHE_SIZE/DB_BLOCK_SIZE)的兩倍大的質數通常能夠消除這個問題。在Oracle9i之前的版本中,這個引數的預設值會引起對該latch的激烈競爭,而在Oracle9i中,該預設值被正確地設定為一個質數。

cache buffers LRU chain latch:cache buffers LRU chain latch 被用於掃描包括快取中所有塊的(最近最少使用)LRU鏈。小的快取區、過大的快取吞吐量、許多基於快取的排序、要滿足工作負荷要求的資料庫書寫器程式(DBWR)的失敗都會導致該問題的發生。試著調整引起過多邏輯讀的查詢。你可以增大初始化引數_DB_BLOCK_LRU_LATCHESOracle9i中),從而擁有更多的LRU latch以降低競爭程度。一般來說,非SMP (symmetric multiprocessing,對稱多處理)機器只需要一個LRU latchOracle自動將其設定為SMP機器上CPU數目的一半。對每個資料庫書寫器,你至少必須有一個LRU latch;如果你新增了資料庫書寫器,請確保增加LRU latch的數目。

library cache latch和shared pool latch(共享池latch): library cache latch連續訪問庫快取中的物件。每次執行一個SQLPL/SQL過程、包、函式或觸發器時,要使用該latch。該latch還用於解析操作期間。

Oracle8i中,有一個單一的 shared pool latch保護庫快取中的記憶體分配。現在,在Oracle9i中,有7個子latch用於保護庫快取中的記憶體分配,這有助於降低對latch競爭程度。

shared pool latchlibrary cache pin latchlibrary cache latch的爭奪一般發生在共享池太小或沒有重用語句時。當沒有使用繫結變數時,語句通常不被重複使用。單純地增加共享池的大小會使這個latch問題變得更糟,因為使用者用大量沒有使用繫結變數的語句填充共享池,這將把帶有大量沒有使用繫結變數的其他語句的經過擴充套件的共享池用光。你也可以設定CURSOR_SHARING= FORCE (或者在Oracle9i中設定 CURSOR_SHARING=SIMILAR)初始化引數來幫助解決這個問題,並減少沒有使用繫結變數時的問題。但是,當對於需要處理的SQL語句的數目來說,庫快取被設定得太小、需要空間時,shared pool latchlibrary cache latch問題也會發生。雖然為裝載一個SQLPL/SQL語句釋放了空間,但是該latch仍然被保持為排他性的,其他使用者必須等待。你可以透過增大

共享池或者透過使用DBMS_SHARED_POOL.KEEP過程將大的SQLPL/SQL語句固定在記憶體中,來幫助降低對latch的競爭程度。

redo allocation latchredo allocation latch用於分配重做日誌緩衝區中的空間,透過使用NOLOGGING特性,可以降低latch競爭程度。NOLOGGING特性用於減少重做日誌緩衝區的負荷。你也可以試著避免不必要的提交。redo copy latch:預設情況下,redo copy latch的數目是CPU數目( CPU_ COUNT)的兩倍,但是也可以透過使用_LOG _SIMULTANEOUS_COPIES初始化引數來設定它。增加該引數可能有助於減少對redo copy latch的爭奪,redo copy latch用於將重做日誌記錄從PGA中複製到重做日誌緩衝區中。

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

相關文章