latch等待事件汇总

主要的等待事件有以下几种:

1.l atch free

Latch free等待事件的三个参数:p1-latch的地址;p2-latch编号;p3-请求次数。从oracle10g起,latchfree不再包含所有的latch等待,有些latch等待可能表现为单独的等待事件,这个后面有提到一些这样的等待事件,一般情况下我们还是统称为latch free等待事件。

如果我们在v$session_wait中发现有latch free等待事件,就意味着,进程在请求一个willing_to_wait模式的latch,在重试了_spin_count次后还是没有获得latch,然后转入睡眠状态了。如果latch争用严重,将会由于不断的spin导致cpu资源紧张,从而增加系统响应时间。


2.latch: shared pool  和 latch: library cache

Shared pool latch主要用来保护共享池的内存结构,当分配或者释放共享池内存时需要先获得该latch。例如,为一个新的sql语句或pl/sql过程、函数、包,触发器等分配空间(硬解析)时,或者为换出、清除某些内存块,以便为新的对象腾出足够的空间时,都需要获取shared pool latch。库缓存中主要保存游标,sql语句,执行计划,分析树等。这些结构由library cache latch保护。当oracle进程修改、检查、销连接(pinning)、锁定、装载,或者执行库缓存中的结构时,都需要先获得library cache latch。通过查询v$latch_children可以得知当前实例中的library cache子latch的个数。

wKiom1RkGzzA6588AAG5zh2DItM951.jpg

图片转载 https://blog.51cto.com/tiany/1575964


当出现Latch竞争严重的时候: 
(1).如果同时出现大量的 Share Pool Latch 和 Library Cache Latch 的话,根据上面的逻辑那说明数 据库中存在大量的硬解析,这个时候就要查找那些 SQL 没有绑定变量。 
(2).如果只是出现大量的 Library Cache Latch 的话,那么可能有两种情况: 
1) 当持有 Library Cache Latch 查找 Bucket 对应的 Chain 时候,发现存在高 Version 的 SQL,这个时候就要扫描这些对应的子游标,整个过程将一直持有 Latch,导致其他会话获取不到 Latch 进行操作。

2) 大量的并发请求,而且不能实现 SQL 一次 Parse Call 多次 Execution。


3.

(1).library cache pin ,library cache lock

1).Lock 与 pin 都用于访问在 library cache 中的对象。Lock 管理不同进程间的并发,pin 则管理缓冲区的一致性。为了访问一个对象,进程必须首先锁定(lock)这个对象的句柄(handle),然后它自己 pin 住对象的内存堆。 
2).Lock 与 pin 请求会一直等待直到获得为止,这是一个引起争用的可能的原因,因为它没有 NOWAIT 请求模式。 
3).Oracle 在分析/编译 Package/Procedure/Function/View 时需要 Library Cache Lock 和 Library Cache Pin。这是为了确保在分析/编译期间, 没有其它人可以对这些对象的定义进行改变,或者删除、重建这个对象。 
4).当一个 SQL 语句被一个 session 硬解析时,这个 session 需要获得一个 library cache lock 以便阻止其它 session 去访问或修改同一个对象。如果这个事件等待很长时间。这表明可能 shared pool 过小或经常发生对象被 flush 出去的情形。这表明数据库对象被经常修改。 

5).除了硬解析,如果一个 session 要更改被 SQL 语句引用的对象的定义或对其做任何更改,就必须获得一个 library cache lock 和 library cache pin。需要 Pin 的原因是需要加载数据字典信息到内存中来修改这个对象。


6).如何降低 library cache lock 等待 
   我们首先要确认的是 library cache 的竞争是整个系统层面的还是只发生在某个或某些 SQL 语句上。这个"library cache lock"是被一个特定的 SQL 持有很长的时间吗?或者总是在等待某个特定的对象?还是说这个锁在短时间内被请求的次数很多从而造成的竞争? 
- 如果问题是在整个系统层面发生的,一般来说是由于 shared pool 太小或 SQL 语句不共享造成的。一些解决竞争的方法: 
增大 shared pool 从而减少 reload 的次数,这是因为 shared pool 过小会造成获取锁的时间加长。 
- 如果您发现是某条或某些SQL产生的问题,那么需要检查为什么它持有锁的时间会那么长。 
以下文档可以用来找到谁在持有锁以及在哪个对象上: 
Note 122793.1 How to Find which Session is Holding a Particular Library Cache Lock 


7).如何降低 library cache pin 等待 
如果"library cache pin"等待的时间很长那么很重要的一点就是判断是只有一两个 process 在等待还是有很多的 process 都在等待。 
如果说只是一两个 process 被另一个 process 阻塞的话,那么需要检查持有这个 pin 的 process 为什么这么长时间不释放。 

如果说等待是大范围的那么说明 shared pool 需要优化。


(2).library cache load lock

如果一个对象不在内存中,那么我们不能对其申请 library cache lock。因此,需要将这个对象加载到内存中。然后,session 尝试找到数据库对象的 load lock,以便它能载入这个对象。为了阻止多进程同时请求加载同一个对象,其它同样请求的 session 将等待 library cache load lock 因为这个对象正在被加载到内存中。等待 library cache load lock 是由于对象在内存中是不存在的。 Library cache 中的对象不存在,是由于 shared pool 过小引起的频繁重新装载,或太多的硬解析缘于不共享的 SQL。 

解决方法:

- 增加 shared pool(避免 reload). 
- 增加 session cached cursors(避免 cursor 被刷出 shared pool) 
- 设置 cursor_sharing 为 force(减少硬解析)。---可能改变执行计划与查询的性能,所以要作充分的测试。


4.latch: row cache objects

用来保护数据字典缓冲区(row cache的名字主要是因为其中的信息是按行存储的,而不是按块存储)。进程在装载、引用或者清除数据字典缓冲区中的对象时必须获得该latch。在oracle8i之前,这是一个独立latch。从oracle9i起,由于引入了多个子共享池的新特性,存在多个row cacheobjects子latch。Oracle10g中,该latch也有了一个独立的等待事件:rowcache objects。


解决方法:

(1).确认SGA 中的share pool 是否还有空闲空间

select POOL,BYTES/1024/1024 FREE_MB from v$sgastat a where a.NAME like  'free%';


(2).查询ROW CACHE中的GET量及命中率

SELECT  r.cache#,r.parameter name,r.TYPE,r.subordinate#,r.gets,r.GETMISSES,round((1 - r.GETMISSES/r.gets)*100,2) SUC_PCT FROM v$rowcache r where r.gets <>0 ORDER BY 5 desc;


SQL解析到底哪一步访问了ROWCACHE,哪一步争用的latch?

这个问题我查询了好久,我之前以为只是在语义检查需要到row cache,其实是在生成执行计划的时候需要访问的数据字典次数更多,争用latch也就更频繁了,所以这里才是最慢的。


5.cache buffers chains

http://blog.itpub.net/15412087/viewspace-2148426/

郑州妇科医院:http://jbk.39.net/yiyuanzaixian/sysdfkyy/

6.latch: cache buffers lru chain

一般来讲,当进程需要查找可用的缓存空间时,需要访问lru列表。后台进程DBWn则会将lruw列表中的干净块移到lru列表中,也会将lru中的脏块移到lruw列表中。在一个工作集中进行以上的任何操作都需要先获得cache bufferslru chain latch。

各个数据缓冲区中(包括不同块大小的缓冲区,keep池和recycle池),每个缓冲区至少需要有一个cache buffers lruchain latch,而一个DBWn进程可能需要多个latch。否则,一个工作集就可能变得很长。在oracle9i和oracle10g中,cache buffers lru chain latch的个数默认是cpu个数的4倍,如果,db_writer_processes大于4,则等于cpu的个数乘以db_writer_processes。可以通过隐含参数_db_block_lru_latches来调节cache buffers lru chain latch的个数。

Cache buffers laru cahin latch的争用,主要表现为由于低效的sql语句导致数据缓冲区过度活跃。全表扫描和对某些选择性较差的大索引的反复扫描是造成cache buffers laru cahin latch争用的主要原因。解决办法是,查找latch free等待事件中关于cache buffers lru chain latch相关的sql语句(在oracle10g中,已经变成一个独立的cache buffers lru chain等待事件),优化这些sql,降低其物理读和逻辑读。


猜你喜欢

转载自blog.51cto.com/14337216/2421990
今日推荐