关于latch的一点点理解

        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就会加一。

原文地址:https://www.cnblogs.com/hehe520/p/6330665.html