Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1128126
  • 博文数量: 276
  • 博客积分: 10077
  • 博客等级: 上将
  • 技术积分: 2513
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-24 20:31
文章分类

全部博文(276)

文章存档

2020年(1)

2015年(5)

2012年(2)

2011年(6)

2010年(7)

2009年(224)

2008年(31)

我的朋友

分类: Oracle

2009-07-07 10:06:04

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中复制到重做日志缓冲区中。

阅读(1393) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~