ITPub博客

首页 > 数据库 > Oracle > library cache pin等待事件的模拟

library cache pin等待事件的模拟

原创 Oracle 作者:llnnmc 时间:2017-05-03 12:11:18 0 删除 编辑

library cache pin是用来管理library cache的并发访问的。pin一个object会引起相应的heap被载入内存(如果此前没有被加载),pins可以在Null、Share、Exlusive这三种模式下获得,可以认为pin是一种特定形式的锁。当library cache pin等待事件出现时,通常说明该pin被其他用户以非兼容模式持有,它一般发生在编译或重新编译PL/SQL、VIEW、TYPES等object时。编译通常都是显性的,但alter、grant、revoke等操作也会使object变得无效,可以通过object的last_ddl_time观察到这些变化。当object变得无效时,oracle会在第一次访问此object时试图去重新编译它,如果此时其他session已经把此object pin到library cache中,就会出现问题,特别是当有大量的活动session并且存在较复杂的dependence时。某些情况下,重新编译object可能花费很长时间,从而阻塞其他试图访问该object的进程。以下通过一个例子来模拟和解释这个等待。

 

1、创建测试用存储过程

 

create or replace procedure pining is

begin

    null;

end;

/

create or replace procedure calling is

begin

    pining;

    dbms_lock.sleep(3000);

end;

/

 

2、模拟竞争

 

session 1:

exec calling;

 

calling中调用pining,此时pining过程上获得共享pin,如果此时尝试对pining进行授权或重新编译,将产生library cache pin等待,直到calling执行完毕。

 

session 2:

grant execute on pining to scott;

revoke execute on pining from scott;

 

此时session2被挂起。

 

3、原因分析

 

从v$session_wait入手,得到哪些会话正在经历library cache pin的等待

col event for a30

col p1text for a20

col p2text for a20

col p3text for a20

col wait_class for a20

select t.sid, seq#, t.event, t.p1text, t.p1, t.p1raw, t.p2text, t.p2, t.p2raw, t.p3text, t.p3, t.p3raw, t.wait_class#, t.wait_class, t.wait_time, t.seconds_in_wait, t.state from v$session_wait t where event like 'library%';

 

       SID       SEQ# EVENT                          P1TEXT                       P1 P1RAW            P2TEXT                       P2 P2RAW            P3TEXT                       P3 P3RAW            WAIT_CLASS# WAIT_CLASS            WAIT_TIME SECONDS_IN_WAIT STATE

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

       142         42 library cache pin              handle address       8791880329 000007FF04E76AD8 pin address          8791880412 000007FF04E8AED8 100*mode+namespace   1061758865 0000609100010003           4 Concurrency                   0              52 WAITING

 

对于library cache pin等待事件,参数p1raw表示等待对象的handle,查询x$kglob,可以得到对象的具体信息

col kglnaown for a10

col kglnaobj for a20

select addr, kglhdadr, kglhdpar, kglnaown, kglnaobj, kglnahsh, kglhdobj from x$kglob where kglhdadr = '000007FF04E76AD8';

 

ADDR             KGLHDADR         KGLHDPAR         KGLNAOWN   KGLNAOBJ               KGLNAHSH KGLHDOBJ

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

000000001F6523A8 000007FF04E76AD8 000007FF04E76AD8 SYS        PINING               1587262593 000007FF04E6ED60

 

上面两个查询可以结合一下,直接获得library cache pin等待的对象

col kglnaown for a10

col kglnaobj for a20

select addr, kglhdadr, kglhdpar, kglnaown, kglnaobj, kglnahsh, kglhdobj from x$kglob where kglhdadr in

  (select p1raw from v$session_wait where event like 'library%');

 

ADDR             KGLHDADR         KGLHDPAR         KGLNAOWN   KGLNAOBJ               KGLNAHSH KGLHDOBJ

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

000000001F651390 000007FF04E76AD8 000007FF04E76AD8 SYS        PINING               1587262593 000007FF04E6ED60

 

获得持有等待对象的session信息

col username for a10

col program for a20

select a.sid,

       a.username,

       a.program,

       b.addr,

       b.kglpnadr,

       b.kglpnuse,

       b.kglpnses,

       b.kglpnhdl,

       b.kglpnlck,

       b.kglpnmod,

       b.kglpnreq

  from v$session a, x$kglpn b

 where a.saddr = b.kglpnuse

   and b.kglpnmod <> 0

   and b.kglpnhdl in

       (select p1raw from v$session_wait where event like 'library%');

 

       SID USERNAME   PROGRAM              ADDR             KGLPNADR         KGLPNUSE         KGLPNSES         KGLPNHDL         KGLPNLCK           KGLPNMOD   KGLPNREQ

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

       141 SYS        sqlplus.exe          000000001F652648 000007FF04F15960 000007FF0BE2D6F8 000007FF0BE2D6F8 000007FF04E76AD8 000007FF04F15A60          2          0

 

该会话正在等待一次PL/SQL lock timer计时

select event from v$session_wait where sid = 141;

 

EVENT

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

PL/SQL lock timer

 

获得持有对象用户执行的代码

select sql_text

  from v$sqlarea

 where (v$sqlarea.address, v$sqlarea.hash_value) in

       (select sql_address, sql_hash_value

          from v$session

         where sid in (select sid

                         from v$session a, x$kglpn b

                        where a.saddr = b.kglpnuse

                          and b.kglpnmod <> 0

                          and b.kglpnhdl in

                              (select p1raw

                                 from v$session_wait

                                where event like 'library%')));

 

SQL_TEXT

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

BEGIN calling; END;

 

于是检查calling, 发现dbms_lock.sleep(3000),也就是141会话出现的PL/SQL lock timer等待,从而找到了142会话发生library cache pin等待的原因。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28974745/viewspace-2138334/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
刘鲁宁的个人博客。

注册时间:2016-12-29

  • 博文量
    113
  • 访问量
    287722