天天看點

latch wait events

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 Support的MetaLink站點。)當latch失敗率大于0.5%時,就應該對這一問題進行研究。(下面你将了解到如何确定latch失敗率。)

latch有兩種類型:願意等待的(willing-to-wait)latch和不願意等待的(not-willing-to-wait)latch,第一種願意等待一個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$LATCHHOLDER、V$LATCHNAME和V$LATCH_CHILDREN對研究latch問題也是有幫助的。

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

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

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

row cache objects(行緩存對象)latch:row cache objects latch 争用通常意味着在資料字典裡存在競争。這一問題也可能是對依賴于公共同義詞的SQL語句解析過度的征兆。一般來說,增大共享池可以解決這一latch問題。你通常可以在它成為一個問題之前,增大共享池以解決library cache latch問題。 cache buffers chains latch:cache-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_LATCHES(Oracle9i中),進而擁有更多的LRU latch以降低競争程度。一般來說,非SMP (symmetric multiprocessing,對稱多處理)機器隻需要一個LRU latch。Oracle自動将其設定為SMP機器上CPU數目的一半。對每個資料庫書寫器,你至少必須有一個LRU latch;如果你添加了資料庫書寫器,請確定增加LRU latch的數目。

library cache latch和shared pool latch(共享池latch): library cache latch連續通路庫緩存中的對象。每次執行一個SQL或PL/SQL過程、包、函數或觸發器時,要使用該latch。該latch還用于解析操作期間。

在Oracle8i中,有一個單一的 shared pool latch保護庫緩存中的記憶體配置設定。現在,在Oracle9i中,有7個子latch用于保護庫緩存中的記憶體配置設定,這有助于降低對latch競争程度。

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

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

redo allocation latch:redo 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/104152/viewspace-139938/,如需轉載,請注明出處,否則将追究法律責任。

轉載于:http://blog.itpub.net/104152/viewspace-139938/