高峰期谨慎编译业务对象

来源:这里教程网 时间:2026-03-03 18:11:32 作者:

在日常运维中,“library cache”相关等待较为常见,主要分为“library cache lock”或“library cache pin”,前者维护“library object handle”上的并发访问,后者维护“library object handle”下对应heap的并发访问,lock管理并发,pin管理一致性。

当我们编译存储过程、函数或视图的时候,Oracle  就会在这些对象的handle  上获得一个“library cache lock  ”,然后在这些对象的heap  上获得pin  ,这样就能保证在编译的时候其他进程不会来更改这些对象。

有了以上的理论基础,当高峰期编译对象出现会话堵塞的问题时,我们应该如何处理呢?  这里主要会用到基表DBA_KGLLOCK  ,其包含如下两个字段。

  kgllkuse  字段:“Address of the user session that holds the lock or pin  ”,主要用于记录持有lock  pin  的用户地址。

  kgllkhdl  字段:“Address of the handle for the KGL object  ”,记录handle  对象地址。

故障发生时,首先查看后台等待事件,命令及输出具体如下:

SQL> select inst_id,sid, event, p1,p1text,p1raw,p2,p2text,p2raw from gv$session where wait_class<>'Idle';

 

INST_ID  SID EVENT                      P1 P1TEXT           P1RAW                    P2 P2TEXT       P2RAW

------- ---- ------------------ ---------- ---------------- ---------------- ---------- ------------ ----------------

      1   33 library cache pin  2081944584 handle address   000000007C17F408 2087901056 pin address  000000007C72D780

根据等待事件“library cache pin  ”获取“p1 handle address 000000007C17F408  ”。

关联视图“dba_kgllock dk,v$session  ”获取锁信息,命令及输出如下:

SQL> select s.sid,s.sql_id,s.event,dk.* from dba_kgllock dk,v$session s where s.saddr = dk.KGLLKUSE and KGLLKHDL='000000007C17F408';

 

SID SQL_ID        EVENT              KGLLKUSE         KGLLKHDL         KGLLKMOD KGLLKREQ KGLL

--- ------------- ------------------ ---------------- ---------------- -------- -------- ----

 33 087rrdjwc2act library cache pin  00000000A92FC040 000000007C17F408        3        0 Lock

 33 087rrdjwc2act library cache pin  00000000A92FC040 000000007C17F408        0        3 Pin

从以上返回结果中可以看出,我们并没有找到pin  的持有者,KGLLKREQ  表示当前会话需要申请的锁模式,KGLLKMOD  表示当前系统中持有的锁模式,由于该系统为RAC  ,各节点之间内存结构不同,handle address  不能公用,因此我们需要定位出owner  object_name  在其他节点持有pin  的会话。命令及输出如下:

SQL> select ADDR,INDX,INST_ID,KGLHDADR,KGLNAOWN,KGLNAOBJ from x$kglob where KGLHDADR='000000007C17F408';

 

ADDR             INDX INST_ID KGLHDADR         KGLNAOWN   KGLNAOBJ

---------------- ---- ------- ---------------- ---------- ---------

00007FE9B0B45850 4979       1 000000007C17F408 SYS        DUMMY

其中,x$kglob  为“library cache object  ”对象的视图。

RAC 2  节点根据object_name  查找对应的handle address  信息,命令及输出如下:

SQL> select ADDR,INDX,INST_ID,KGLHDADR,KGLNAOWN,KGLNAOBJ from x$kglob where KGLNAOBJ='DUMMY'

 

ADDR             INDX INST_ID KGLHDADR         KGLNAOWN  KGLNAOBJ

---------------- ---- ------- ---------------- --------- ---------

00007F987B1D8ED0 4150       2 00000000AA193870 SYS       DUMMY

查看锁的持有情况,命令及输出如下:

SQL> select s.sid,s.sql_id,s.event,dk.* from dba_kgllock dk,v$session s where s.saddr = dk.KGLLKUSE and KGLLKHDL='00000000AA193870';

 

SID SQL_ID        EVENT             KGLLKUSE         KGLLKHDL         KGLLKMOD  KGLLKREQ KGLL

--- ------------- ----------------- ---------------- ---------------- --------  -------- ----

424 d4wnj5j8y1mq7 PL/SQL lock timer 00000000A9787DA0 00000000AA193870        1         0 Lock

424 d4wnj5j8y1mq7 PL/SQL lock timer 00000000A9787DA0 00000000AA193870        2         0 Pin

最终定位  2  上的会话424  其持有模式为(即共享模式)的锁,堵塞了KGLLKREQ 3  排它锁的申请,为了能够顺利编译,我们只需要杀掉节点上的会话424  即可。


   像“节点”“节点”“节点”,是否可以改为“节点”“节点”“节点”?

相关推荐