oracle常见异常等待——latch处理思路

来源:这里教程网 时间:2026-03-03 17:57:17 作者:

library cache pin/lock  

     library cache lock/pin发生在多个session对相同library cache对象进行争用发生,一般来说在对象进行DDL时候发生,如:存储过程编译过程中发生并堵塞编译/表修改   解决方案:

======堵塞者和被堵塞者在同一节点

set linesize 500

col spid format a10

col username format a15 

col machine format a15 

col program format a20

col sql_fulltext format a100 

select b.spid,a.sid,a.username,a.machine,a.program,c.sql_fulltext

from v$session a,v$process b,v$sql c

where a.paddr=b.addr

and a.sql_id=c.sql_id

and a.paddr in

      (SELECT s.paddr   FROM x$kglpn p, v$session s

        WHERE p.kglpnuse = s.saddr(+)     AND p.kglpnmod <> 0     and kglpnhdl in

              (select p1raw     from v$session_wait     where event in (&#39;library cache pin&#39;, &#39;library cache lock&#39;,   &#39;library cache load lock&#39;)

              )

      );

/




======堵塞者和被堵塞者在不同一节点

1.在问题节点,查看是什么对象被PIN 在library cache中

set linesize 300

col owner for a20

col object for a20

SELECT KGLNAOWN owner,KGLNAOBJ object

  FROM x$kglob

  WHERE kglhdadr in(select P1RAW from v$session_wait where event like &#39;library cache%&#39;);







2、在另外节点执行(带入上一个语句执行出的KGLNAOBJ)

set linesize 300

col sql_text for a100

select sid, serial#, sql_text from dba_kgllock w, v$session s, v$sqlarea a

where w.kgllkuse = s.saddr 

and s.sql_address = a.address

and s.sql_hash_value = a.hash_value

And w.kgllkhdl =(select kglhdadr from x$kglob where kglnaobj = &#39;PRO_YJB&#39;);

Latch:Library Cache  

     原因:为了寻找空闲Chunk,通过shared pool锁存器,实现保护扫描空闲列和分配适当Chunk;为了执行SQL。通过library cache锁存器,保护检索并管理库高速缓冲区的所有工作。在获得library cache锁存器过程中,若发生争用,则等待latch:library cache事件。library cache 锁存器争用主要在如下情况下发生:   1、Hard Parsing 或Soft Parsing 过多时   2、Version count如果很高,也会引发这个问题,因为找到handle以后, 对child的搜索是用遍历的方式,如果version很高child很多,则每次搜索的时间很可能会变长。会造成对handle上的锁,持有的时间也变长。   3、SGA区域发生Page out时,增加session_cache_cursors是个可能的尝试,如果cursor被cache住,child的位置会被保存在pga中,那么查找child的速度会明显加快

library cache: mutex X  

    11G以后,latch:library cache被替换为library cache: mutex X。锁的粒度变小,每个bucket和每个handle都被一个单独的mutex保护,大幅度减小了争用   1、当发生硬解析时,无论要创建一个新的handle,还是要创建一个新的Child,都需要额外大量的时间来完成,相应地,对这个mutex的持有时间会明显变长,造成争用。由于硬解析会向shared pool申请大量的内存,因此这种情况会伴随一系列其他等待如 latch: shared pool, library cache load lock。 解决办法就是分析硬解析过多,或者version count过高的问题。   2、OS资源不足,特别是CPU资源紧张。 这种情况下,oracle进程无法获取足够的资源去完成相应的工作,无法及时释放此mutex,造成请求的堆积。   3、再有,就是某个持有者长时间不释放此mutex,造成请求的积压。这是不正常的, 需要对mutex持有者的当前状态进行分析。 Errorstack, process dump。 如果持有者被其他进程阻塞,则通过hanganalyze等工具继续查找最终持有者   4、个别Oracle bug也会造成此类问题

latch:cache buffers chains  

     原因:欲在高速缓冲区上搜索特定块的进程,需要获得cache buffers chains锁存器。在此过程中,若发生争用,则等待latch:cache buffers chains事件。  

   1、不够优化的SQL。   大量逻辑读的SQL语句就有可能产生非常严重的latch:cache buffers chains等待,因为每次要访问一个block,就需要获得该latch,由于有大量的逻辑读,那么就增加了latch:cache buffers chains争用的机率。   对于正在运行的SQL语句,产生非常严重的latch:cache buffers chains争用,可以利用下面SQL查看执行计划,并设法优化SQL语句。select * from table(dbms_xplan.display_cursor('sql_id',sql_child_number));   如果SQL已经运行完毕,我们就看AWR报表里面的SQL Statistics->SQL ordered by Gets->Gets per Exec,试图优化这些SQL。  

   2、热点块争用  

2.1 查找数据库是否存在latch的争用select sid,event,p1text,p1raw from v$session_wait where event='latch: cache buffers chains';   

2.2 下面查询查出Top 5 的争用的latch address。

select * from( select CHILD#,ADDR,GETS ,MISSES,SLEEPS from v$latch_children where name = 'cache buffers chains' and misses>0 and sleeps>0 order by 5 desc, 1, 2, 3) where rownum<6;

   3、然后利用下面查询找出Hot block。    

select /*+ RULE */       e.owner ||'.'|| e.segment_name segment_name,       e.extent_id extent#,       x.dbablk - e.block_id + 1 block#,       x.tch, /* sometimes tch=0,we need to see tim */x.tim ,l.child#     from       v$latch_children l,       x$bh x,       dba_extents e     where       x.hladdr = '&amp;ADDR' and       e.file_id = x.file# and       x.hladdr = l.addr and       x.dbablk between e.block_id and e.block_id + e.blocks -1     order by x.tch desc ;       e.owner ||'.'|| e.segment_name segment_name,       e.extent_id extent#,       x.dbablk - e.block_id + 1 block#,       x.tch, /* sometimes tch=0,we need to see tim */x.tim ,l.child#     from       v$latch_children l,       x$bh x,       dba_extents e     where       x.hladdr = '&amp;ADDR' and       e.file_id = x.file# and       x.hladdr = l.addr and       x.dbablk between e.block_id and e.block_id + e.blocks -1     order by x.tch desc ;

   4、Hash Bucket太少   需要更改_db_block_hash_buckets隐含参数。其实在Oracle9i之后,我们基本上不会遇到这个问题了,除非遇到Bug。所以这个是不推荐的,记住,在对Oracle的隐含参数做修改之前一定要咨询Oracle Support。

latch:buffer cache lru chain  

      原因:高速缓冲区上与搜索空闲缓冲区(free buffer)和脏缓冲区(dirty buffer)的进程,需要获得cache buffers lru chain锁存器。在此过程中,若发生争用,则等待latch:cache buffers lru chain事件。  

     1、适当增大 Buffer Cache,这样可以减少读数据到 Buffer Cache 的机会,减少扫Lru List 的竞争。 

  2、可以适当增加 LRU Latch 的数量,修改_db_block_lru_latches 参数可以实现,但是该参数通常来说是足够的,除非在 Oracle Support 的建议下或确知该参数将带来的影响,否则不推荐修改。  

     3、通过多缓冲池技术,可以减少不希望的数据老化和全表扫等操作对于 Default池的冲击,从而可以减少竞争。  

     4、优化 SQL,减少数据读取,从而减少对于 LRU List 的扫描

相关推荐