latch - Concept

latch介绍:

Oracle RDBMS使用了几种不同类型的锁机制。主要是latch,equeues,distributed locks和
global locks(在并行实例中执行)

1. 什么是latch
latch是低层次序列化的机制用来保护SGA中的共享数据结构。latch的执行是依赖操作系统
的,特别是关于是不是进程在等待latch和多长时间。

latch是一种lock类型,可以快速得到并释放。 Latch是用来防止超过一个进程在同
一时间执行同一段代码。和每个latch关联的是一个清楚过程。当持有latch的进程
僵死的时候将执行清楚过程。Latch有一个相关联的层次,用来防止死锁。当一个进
程请求一个层次的latch,就不能在连续请求一个相同或更低层次的latch。(除非
以nowait方式请求)

有3类latch,父latch,子latch,solitary latch。父latch和solitary latch是固定在Oracle
代码中的,子latch是在启动时分配的。

2. latch和enqueue

Enqueue是另外一种类型的锁机制。一个enqueue是个更复杂的机制,它允许并发的进程对
已知的资源有不同程度的共享。任何可以并发使用的对象,可以用enqueue来保护。一个好
的例子是表锁。我们允许不同层次的表共享比如俩个进程以共享模式所表或共享更新方式。
一个不同点是enqueue是使用OS特定锁机制获取的。一个euqneue允许用户在锁上保存一个
值,比如我们正在申请的模式。OS锁管理保持追踪锁定的资源。如果一个进程没有被对锁
授权,因为它不兼容正在申请的模式和锁被以等待的方式申请了。OS将正在申请的进程放
进一个等待队列中,这个队列是按FIFO方式服务。
另外一个不同点是latch中没有一个像enqueue一样的有序的等待队列。Latch等待者可能
使用定时器来唤醒和重试或者spin(只在多处理器中)。因为所有的等待者并发的重试(
根据定时任务),任何一个都可能得到latch,可能的一个尝试,但是却是最后一个得到。

3. 什么时候需要得到一个latch?
当和SGA中的内存结构工作的时候,一个进程获取一个latch。在和内存结构工作的时间中
将继续持有latch。当进程结束和内存结构工作的时候,latch将被删除。每个latch保护
不同结合的数据,用latch的名字标记。

Oracle使用原子指令像“测试和设置”来操作latch。进程等待执行一部分代码,但是这部分
代码的latch已被其他进程获取,那么这个进程只有等latch被释放。比如:redo allocation
latches,copy latches,archive control latch等等。基本的思想是防止并发访问共享
的数据结构。因为设置和释放latch的指令是原子的,OS保证只有一个进程能得到。因为
他是一个指令,它是非常快。Latch只在极短的时间内持有,并提供了一个清楚机制,万一
持有者僵死。这个清楚工作是由PMON进程执行。

4. latch请求模式
latch请求有俩中模式: willing-to-wait或者no wait。正常地,latch将被以
willing-to-wait模式申请。一个willing-to-wait的模式就是循环,等待,再请求直到获得
latch。在no wait模式,如果latch没有空闲,进程将发起另外一个请求,而不是等待。只
有当所有的都失败了,服务器进程才不得不等待。

willing-to-wait的latch的例子是shared pool, library cache latches。用统计信息gets
和misses统计。

no wait的例子是redo copy latch。主要用于棘手的latches。用统计信息immediate_gets
和immediate_misses统计。

5. 什么引起latch争用?
如果一个需求的latch正忙,进程请求,spin,再重试,如果仍然不可用,再spin。这个循
环重复次数使用初始化参数_SPIN_COUNT决定的。如果整个循环后,latch还是不可用,进程
必须让出cpu占有权并进入睡眠期。开始是睡眠百分之一秒。这个时间在后续的睡眠将加倍
这将导致变慢发生,结果是cpu使用率的增加。CPU的使用率是进程spinning的后果。Spinning
意味着一个进程在固定的时间后继续查找可用的latch。

5.1 latch分类
从9i开始,latch可以分成不同的类,每个类有不同的_SPIN_COUNT。默认是20000。

select indx, spin, yield, waittime
from   x$ksllclass;

SQL> select indx, spin, yield, waittime
from   x$ksllclass;
  2 
      INDX       SPIN      YIELD   WAITTIME
---------- ---------- ---------- ----------
         0      20000          0          1
         1      20000          0          1
         2      20000          0          1
         3      20000          0          1
         4      20000          0          1
         5      20000          0          1
         6      20000          0          1
         7      20000          0          1

5.2 latch free等待事件
v$session_wait中的latch free等待事件,表明进程以willing-to-wait模式获取latch失败
并spin了_SPIN_COUNT次数,然后进入了休眠。

5.3 latch miss location
保留在那个oracle内核代码发生了latch丢失信息。

col location format a30
col parent_name format a30
select location
,        parent_name
,        wtr_slp_count
,        sleep_count
,        longhold_count
from v$latch_misses
where  sleep_count > 0
order by wtr_slp_count, location;

LOCATION                       PARENT_NAME                    WTR_SLP_COUNT SLEEP_COUNT LONGHOLD_COUNT
------------------------------ ------------------------------ ------------- ----------- --------------
kcbcge                         cache buffers chains                    2779           8              0
kcbrls: kslbegin               cache buffers chains                    7687         365             12
kcbgtcr: kslbegin excl         cache buffers chains                   21050       23104           1044
kcbchg: kslbegin: call CR func cache buffers chains                   25592          45              0
kcbzwb                         cache buffers chains                   26248       37769            540
kqrpre: find obj               row cache objects                      50025       68746              0
kqrpfl: not dirty              row cache objects                      62093       43359              0
kcbchg: kslbegin: bufs not pin cache buffers chains                  112667      134624              0
ned                                                                                    

WTR_SLP_COUNT - 等待者睡眠的次数。
SLEEP_COUNT - 请求latch导致睡眠的次数。
LONGHOLD_COUNT - 在等待者睡眠整个期间,进程持有latch的次数。

6. 如何辨别latch争用
 
    V$LATCH
    V$LATCHHOLDER
    V$LATCHNAME

"willing-to-wait" Hit Ratio=(GETS-MISSES)/GETS
"no wait" Hit Ratio=(IMMEDIATE_GETS-IMMEDIATE_MISSES)/IMMEDIATE_GETS

这些值应该接近1。如果不是,根据latch的名字调优。

6.1 AWR 报表中latch的信息

6.1.1 latch的总体情况。
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:  100.00       Redo NoWait %:    100.00
            Buffer  Hit   %:   99.60    In-memory Sort %:    100.00
            Library Hit   %:   98.02        Soft Parse %:     93.94
         Execute to Parse %:   57.81         Latch Hit %:     98.26
Parse CPU to Parse Elapsd %:   98.40     % Non-Parse CPU:     97.86
latch hit% - 表示latch命中率。
"willing-to-wait" Hit Ratio=(GETS-MISSES)/GETS
"no wait" Hit Ratio=(IMMEDIATE_GETS-IMMEDIATE_MISSES)/IMMEDIATE_GETS

6.1.2 top 5等待事件
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~                                                     % Total
Event                                               Waits    Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
latch free                                      2,048,146       3,805    31.39
CPU time                                                        3,613    29.81
enqueue                                            88,999       2,631    21.71
db file sequential read                           151,409         656     5.41
SQL*Net break/reset to client                     213,028         506     4.17

如果latch free进入top 5等待事件,需要关注。

6.1.3 latch的明细的信息:
Latch Activity for DB: DBS  Instance: TESTDB  Snaps: 67875 -67876
->"Get Requests", "Pct Get Miss" and "Avg Slps/Miss" are statistics for
  willing-to-wait latch get requests
->"NoWait Requests", "Pct NoWait Miss" are for no-wait latch get requests
->"Pct Misses" for both should be very close to 0.0

                                           Pct    Avg   Wait                 Pct
                              Get          Get   Slps   Time       NoWait NoWait
Latch                       Requests      Miss  /Miss    (s)     Requests   Miss
------------------------ -------------- ------ ------ ------ ------------ ------
Consistent RBA                  864,907    0.0    0.0      0            0
FAL request queue                    53    0.0             0            0
FAL subheap alocation                 4    0.0             0            0
FIB s.o chain latch                  20    0.0             0            0
FOB s.o list latch                9,957    0.0             0            0
SQL memory manager latch              1    0.0             0          300    0.0
SQL memory manager worka         74,661    0.0             0            0
active checkpoint queue       3,187,342    1.6    0.0      0            0
alert log latch                   1,560    0.0             0            0
archive control                     167    0.0             0            0
archive process latch                65    0.0             0            0
begin backup scn array                1    0.0             0            0
cache buffer handles             21,551    0.0             0            0
cache buffers chains        454,626,669    0.0    0.0     10    1,779,732    0.0
cache buffers lru chain         605,800    0.0    0.0      0    2,021,496    0.0
channel handle pool latc         10,848    0.0    0.0      0            0
channel operations paren         16,942    0.0    0.0      0            0
checkpoint queue latch    1,140,976,890    0.0    0.0      0      140,838    0.0
undo global data            434,079,118    3.2    0.1   3624            0

latch - latch名字
get requests - 以willing-to-wait模式请求latch次数
Pct Get miss - 以willing-to-wait模式请求latch次数时必须等待的百分比
Avg Slps/Miss - 以willing-to-wait模式请求latch,然后一直在等待直至sleeps,平均每次等待产生睡眠的比例。
Wait Time(s) - 等待的总时间(s)
NoWait Requests - 以no-wait模式请求的次数
Pct NoWait Miss - 以no-wait模式请求的没有成功的次数所占用的百分比。

6.1.4 latch的分解信息:
Latch Sleep breakdown for DB: TESTDB  Instance: TESTDB  Snaps: 67875 -67876
-> ordered by misses desc

                                      Get                            Spin &
Latch Name                       Requests      Misses      Sleeps Sleeps 1->4
-------------------------- -------------- ----------- ----------- ------------
undo global data              434,079,118  13,791,770   1,625,558 12511367/999
                                                                  134/229060/5
                                                                  2209/0
row cache enqueue latch        50,931,324  12,107,941       1,582 12106361/157
                                                                  8/2/0/0
enqueues                       36,426,041  10,113,124       4,838 10108419/457
                                                                  5/127/3/0
row cache objects              50,987,843   4,915,932     286,380 4660648/2286
                                                                  28/22776/388
                                                                  0/0
transaction allocation        222,110,544   1,299,459     133,733 1240084/3043
                                                                  1/12467/1647
                                                                  7/0
enqueue hash chains            47,365,639     550,422         337 550085/337/0
                                                                  /0/0
latch - latch名字
get requests - 以willing-to-wait模式请求latch次数
misses - 请求latch时必须等待的次数
sleeps - 请求latch未能正常获取,导致等待直至sleeps的次数。
Spin &Sleeps 1->4 - 以willing-to-wait模式请求latch,在第一次尝试时失败,但是在spin时成功的次数。第1->4次休眠的次数。

6.1.4 latch的来源信息:
Latch Miss Sources for DB: TESTDB  Instance: TESTDB  Snaps: 67875 -67876
-> only latches with sleeps are shown
-> ordered by name, sleeps desc

                                                     NoWait              Waiter
Latch Name               Where                       Misses     Sleeps   Sleeps
------------------------ -------------------------- ------- ---------- --------
cache buffers chains     kcbget: exchange rls             0          1        0
cache buffers chains     kcbzib: finish free bufs         0          1        0
cache buffers chains     kcbgtcr: kslbegin shared         0          1        0
cache buffers chains     kcbgtcr                          0          1        0
enqueue hash chains      ksqgtl3                          0        190      219
enqueue hash chains      ksqrcl                           0        145      114
enqueue hash chains      ksqcnl                           0          4        6
enqueues                 ksqgel: create enqueue           0      2,582    2,718
enqueues                 ksqdel                           0      2,253    2,108
enqueues                 ksqies                           0          3       12
library cache            kglic                            0         22      120
shared pool              kghupr1                          0         11      278
shared pool              kghfre                           0          2        6
transaction allocation   ktcxbr                           0    133,733  133,733
undo global data         ktusm_stealext: KSLBEGIN         0  1,606,765 ########
undo global data         ktusmupst: KSLBEGIN              0      6,658    8,743
undo global data         ktucmt: ktugd_cuux               0      5,907    5,182
undo global data         ktusmasp: ktugd_tuux             0      2,910    4,862
undo global data         ktusmasp: ktugd_suux             0      2,892    4,296
undo global data         ktugnb: ktugd_tuux               0        292      300
undo global data         kturdc: KSLBEGIN                 0        148       77
undo global data         ktudba: KSLBEGIN                 0         81    1,536
undo global data         ktugnb: ktugd_cuux               0          9       11
undo global data         ktudnx:child                     0          7      196
undo global data         ktubnd:child                     0          2       85
undo global data         ktucof: at start                 0          2        1

latch - latch名字
where - latch等待的位置
NoWait misses - 以no-wait模式请求latch时失败的次数
sleeps - 以no-wait模式请求latch时,导致等待直至sleeps的次数。
Waiter Sleeps - 记录进程在此内核位置request对应latch的次数

7. 有用的SQL Scripts得到latch信息

    /*
    ** Display System-wide latch statistics.
    */
    column name format A32 truncate heading "LATCH NAME"
    column pid heading "HOLDER PID"
    select c.name,a.addr,a.gets,a.misses,a.sleeps,
    a.immediate_gets,a.immediate_misses,b.pid
    from v$latch a, v$latchholder b, v$latchname c
    where a.addr = b.laddr(+)
    and a.latch# = c.latch#
    order by a.latch#;

    /*
    ** Given a latch address, find out the latch name.
    */
    column name format a64 heading 'Name'
    select a.name from v$latchname a, v$latch b
    where b.addr = '&addr'
    and b.latch#=a.latch#;

    /*
    ** Display latch statistics by latch name.
    */
    column name format a32 heading 'LATCH NAME'
    column pid heading 'HOLDER PID'
    select c.name,a.addr,a.gets,a.misses,a.sleeps,
    a.immediate_gets,a.immediate_misses,b.pid
    from v$latch a, v$latchholder b, v$latchname c
    where a.addr   = b.laddr(+) and a.latch# = c.latch#
    and c.name like '&latch_name%' order by a.latch#;
    
9. DBA关注的latch
 
BUFFER CACHE LATCHES: 有俩个主要的latch来保护buffer cache的数据块。这俩个
latch的争用经常发生在database过高的IO。我们可以通过调节init.ora的参数来减少latch
的争用。

    Cache buffers chains latch: 只要buffer cache的中块被访问,这个latch就被获取

减少Cache buffers chains latch需要减少逻辑IO,这可以通过优化和最小化SQL的IO需
求。过高的IO可能是一个热块的迹象(意味着一个块被过度访问)。

Cache buffers LRU chain latch:
Cache buffers LRU chain latch这个latch是引入一个新块到buffer cache中和写一个
buffer回到磁盘,特别是扫描LRU(最近使用)链,其中buffer cache包含脏块。
减少cache buffers LRU chain latch需要增加buffer cache的大小,这样就减少新块引入
的几率。可以通过改参数db_cache_size来增大buffer cache。多个buffer pool可以帮助
减少这个latch的争用。你可以通过DB_BLOCK_LRU_LATCHES/_DB_BLOCK_HASH_BUCKETS来增加
cache buffer lru chain。

REDOLOG BUFFER LATCHES: 有俩种reco buffer latches,the redo allocation latch 和
the redo copy latch。redo allocation latch在buffer中分配空间时必须获得。如果重做
日志的条目比LOG_SMALL_ENTRY_MAX_SIZE参数大。已获取redo allocation latch的会话可
能拷贝条目到重做buffer中,如果日志的条目比LOG_SMALL_ENTRY_MAX_SIZE大,那么会话将
立即释放redo allocation latch并请求redo copy latch来拷贝条目。只有一个redo
allocation latch,但是也有最大到LOG_SIMULTANEOUS_COPIES的allocation latches。

    Redo allocation latch:
这个latch控制在重做日志buffer中的重做条目的空间分配。一个实例只有一个redo
allocation latch。

可以通过增加log_buffer来减少log buffer的使用,从而减少redo allocation latch的争
用。也可以通过nologging减少日志文件的负载。

    Redo copy latch:
这个latch用来写重做记录到重做日志buffer中。这个latch在单cpu和多cpu系统中被等待。
     
在多cpu系统中,可以增加LOG_SIMULTANEOUS_COPIES来减少争用。

    LIBRARY CACHE

    Library cache latch:
Libary cache latch保护缓存的SQL statements和shared pool/library cache中的对象定
义。为了增加一个新statement到library cache中Library cache latch必须被获取。在解
析的时候,Oracle在libraray cache中查找一个匹配的statement。如果没有找到,然后
Oracle将解析SQL statement,获取library cache latch,并增加新的SQL。

减少这个latch的争用的第一资源是保证应用尽可能地重用SQL statement。如果有可能,在
应用中使用绑定变量。错过这个latch也是一个迹象,应用在过度地解析SQL,并可能经历太
多解析CPU。

参数_KGL_LATCH_COUNT控制library cache latch的数目。默认值应该足够了,但是如果能
解决这个latch争用,建议可以增加这个值。默认值是比CPU_COUNT大的下一个素数。这个值
不能超过66.

    Library cache pin latch:

The library cache pin latch 当一个library cache中的statement重新执行时必须获得。
错过这个latch发生在过度地SQL执行。

为减少library cache pin latch负载能做的不多,尽管使用私有的同义词而不是使用公共
的同义词,或者使用直接的对象引用比如OWNER.TABLE也许有帮助。


    SHARED POOL RELATED LATCHES

    Shared pool latch:

在分配和释放shared pool中的内存时,Shared pool latch是用来保护重要的操作。如果一
个应用使用常量(非共享)SQL,将严重限制可扩展性和吞吐量。解析一个新的SQL
statement的成本是很高的,包括CPU的要求和library cachehe/shared pool latches获取
和释放的次数。

减少shared pool latch的方法是避免硬分析,解析一次,执行多次。消除常量的SQL也是非
常有用的。

    Row cache objects latch:
这个latch起作用是在用户进程试图访问缓存的数据词典的值。

这个latch上的争用不是很普遍,减少这个latch争用的方法是增加shared pool的大小。

10. 调整_SPIN_COUNT

SPIN_COUNT控制进程在睡眠之前尝试多少次去获取latch。这个基本意思是进程在一个CPU紧
凑的循环中不断地尝试SPIN_COUNT次去获得latch。在一个单cpu系统中,如果一个进程想获
取一个latch,但是这个latch被其他进程持有,这个进程将释放CPU并睡眠很短的时间,然
后重试。然而,在一个多处理器(SMP)系统中,持有latch的进程运行在其他cpu上,并且
可能在很少的指令后就释放latch(latch通常持有很短时间)。

更改SPIN_COUNT的值可能影响性能。如果使用很大的值,latch将比小的值更快地被获得。
然而你将使用更多的CPU时间spinning来获取latch。在latch上的Spinning消耗CPU,所以如
果你增大这个值,CPU的使用率将增高。如果你的CPU是100%,你的系统关注吞吐量,而不是
响应时间,你可以考虑减少SPIN_COUNT。如果CPU资源很宽松,那么你可以增大这个值,如
果没有空余的CPU容量的话,那么就减少这个值。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25105315/viewspace-752715/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25105315/viewspace-752715/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值