高峰期谨慎编译业务对象

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

在日常运维中,“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 ,其包含如下两个字段。

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

q   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 其持有模式为2 (即共享模式)的锁,堵塞了KGLLKREQ 3 排它锁的申请,为了能够顺利编译,我们只需要杀掉节点2 上的会话424 即可。


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

相关推荐