關於latch的一點點理解

lsm_3036發表於2011-08-24

latch是ORACLE中鎖的一種,它是一種低階鎖,是保護SGA中的共享記憶體,它幾乎不排隊(latches wait list除外),不會產生死鎖。

 latch分為no-wait與willing-to-wait模式,以willing-to-wait請求的latch只有少數幾個,而且他們一般都有多個子latch.

 比如redo copy latch,我們知道redo 最開始產生於PGA中,之後會將redo記錄copy到SGA中,要想copy,就需要獲得一個

redo copy latch,防止copy過程中redo記錄被破壞。而redo copy latch的獲取方式是 no-wait方式的,如果請求沒有獲得,它不會在cpu上面自旋(spin,當然你需要有多個CPU),而是繼續以no-wait方式繼續請求,因為有多個redo copy latch,很容易獲得一個redo copy latch,如果所有的redo copy latch都無法獲得,那麼就只好以willing-to-wait模式請求redo copy latch了。

以no-wait模式請求latch,會在v$latch.immediate_gets,immediate_misses中記錄。

       絕大多數的latch都是以will-to-wait模式請求的。他們的資訊會記錄在gets,misses列。

       在多cpu系統中以willing-to-wait模式請求latch過程如下:

       1.請求latch,如果沒有別的程式擁有該latch,那麼直接獲得該latch.

       2.如果latch被別的程式持有,請求該latch的程式在cpu上自旋一段時間,自旋的次數和時間長短由cpu決定。如果是單cpu,不會自旋,直接休眠。

       3.從新嘗試獲得該latch,如果無法獲取(_spin_count次自旋後),記錄一個latch free等待事件,然後釋放cpu,休眠。如果獲得了該latch,則在spin_gets,misses列上加一,自旋的總的次數由_spin_count隱含引數決定。

       4.睡眠結束後,繼續嘗試獲取該latch,直到獲得該latch為止,同時獲得latch的時候會更新sleeps列的資訊。

可以檢視v$system_event.total_waits來檢視latch無法獲取的次數,v$system_event.total_waits應該等於v$latch.sleeps,不過因為sleeps是在latch獲得之後才更新的,所以tatal_waits查詢出來的時候通常大於sleeps。

SQL> select event,total_waits,time_waited,average_wait from v$system_event where event like '%latch%' ;

EVENT                                                            TOTAL_WAITS TIME_WAITED AVERAGE_WAIT
---------------------------------------------------------------- ----------- ----------- ------------
latch: cache buffers chains                                                2           0            0
latch: shared pool                                                         3           0          .06
latch: library cache                                                       1           0          .01
latch free                                                                 6           0            0
latch: session allocation                                                  1           0          .01
latch: cache buffers lru chain                                             3           9         2.86

已選擇6行。

SQL> select name,gets,misses,sleeps,spin_gets from v$latch where sleeps!=0;

NAME                                                     GETS     MISSES     SLEEPS  SPIN_GETS
-------------------------------------------------- ---------- ---------- ---------- ----------
shared pool                                            109039        204          3        201
session allocation                                     264876        307          1        306
cache buffers lru chain                                 19276         19          3         16
qmn task queue latch                                       78          9          6          3
library cache                                           83505         83          1         82
cache buffers chains                                   960520         47          2         46

已選擇6行。

可以看到cache buffers chains 中v$system_event.total_waits等於v$latch.sleeps。

misses通常比spin_gets大,但是他們很接近,gets通常較大,因為每次請求一個latch就會加一。

 

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

相關文章