[RAC Troubleshooting] RAC下的library cache pin与library cache lock
RAC下 library cache pin与library cache lock的成因与single instance无本质区别,都是为了并发时保护shared pool的内存结构,本篇不再赘述其原理。
在日常排查方面,需要注意一些问题。
在single instance下,我们找造成pin或者lock的根源,通常是使用v$sesion_wait.p1raw字段,得到handle地址,关联x$kglpn/v$session等基表或者视图来找到blocker的session信息。
在rac下,如果blocker 和waiter session在不同的实例下,直接通过handle地址就无法获得blocker。因为rac系统每个实例有各自的sga结构,相同的结构对象在各自的library cache里面的handle/heap地址是不相同的。这种情况下,需要通过waiter上pin/lock住的对象名称,去另外的节点上查找该对象的lock/pin持有session信息。
对library cache pin,全局的hanganalyze并不能trace出该等待的blocker和waiter( 对单节点也同样如此),但对library cache lock来讲,hanganalyze 是适用的。如果数据库版本在10g以上,通过v$session BLOCKING_SESSION_STATUS/BLOCKING_INSTANCE/BLOCKING_SESSION 这几个字段,便可获取bloker信息。
下面模拟一下library cache pin.
情况1:blocker、waiter在同一实例节点。
情况2:blocker、waiter在不同实例节点。
说明:
采用2 session完成模拟,一个session用来执行procedure,另外一个用来编译该procedure。
情况1:
node:node1 / session:122
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
———- ———- ———-
122 0 1SQL> exec proc_get_pin;
node:node1 / session:126
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
———- ———- ———-
126 0 1SQL> alter procedure proc_get_pin compile;
查询等待 :
SQL> select sid,event from v$session_wait where event like ‘library%’;
SID EVENT P1RAW
———- —————————————————————-
126 library cache pin 2B9E5B50SQL> SELECT a.SID, a.username, a.program
3 FROM v$session a, x$kglpn b
4 WHERE a.saddr = b.kglpnuse
5 AND b.kglpnmod <> 0
6 AND b.kglpnhdl=’2B9E5B50′SID USERNAME PROGRAM
———- —————————— —————————-
122 TEST sqlplus@node1 (TNS V1-V3)
获得blocker sid: 122.
情况2:
node: node1 / session 121
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
———- ———- ———-
122 0 1SQL> exec proc_get_pin;
node:node2 / session 153
SQL> select * from v$mystat where rownum<2;
SID STATISTIC# VALUE
———- ———- ———-
153 0 1SQL> alter procedure proc_get_pin compile;
在任何一个节点查询gv$session,获得waiter信息。
SQL> select inst_id,sid,event,p1raw from gv$session_wait where event like ‘library%’;
INST_ID SID EVENT P1RAW
———- ———- ———————- ——–
2 153 library cache pin 2B566F0C
从这可以得知,实例2上的session 153被阻塞.
在rac下的任何一个节点,用获得的paraw(handle adress)传入情况1中使用的代码,都无法或者正确的blocker(验证略)
登陆到waiter节点node2,获得等待pin的object.
SQL> select kglnaobj from x$kglob b where b.kglhdadr=’2B566F0C’;
KGLNAOBJ
—————————————————————
PROC_GET_PIN
登陆到其余节点,寻找blocker。
node1:
SQL> select s.sid,s.PROGRAM,b.kglnaobj from v$session s,x$kglpn a,x$kglob b where b.kglnaobj like ‘%PROC_GET_PIN%’ and a.kglpnhdl=b.kglhdadr and s.SADDR=a.kglpnuse and a.KGLPNMOD<>0;
SID PROGRAM KGLNAOBJ
———- ———————————————— ——————————————————————————–
122 sqlplus@node1 (TNS V1-V3) PROC_GET_PIN
如果有其他节点,依次登陆排查。这样,我们就获得了真正的blocker.
对于library cache lock,类似上述方法同样适用。最简便的不受db版本限制的方法就是做个3级的hanganalyze。blocker/waiter关系清晰明了。
SQL>oradebug setmypid
SQL>oradebug setinst all
SQL>oradebug -g all hanganalyze 3
