library cache lock等待事件的概述:
- library cache lock 是在争抢library cache中的资源而造成的资源等待,它有3个参数:p1 对象的地址;p2 锁的地址; p3 namespace等,确定是表、包、索引等。
- 对这个lock的等待,pmon是1秒,其它进程都是3秒
- 出现这个等待时,经常表现的症状是:我们无法进行一些查询,甚至不能desc table_name来查看某个內容。由于等待信息不出现在v$lock中,所以,我们根据v$lock不能够确定其中的原因
解决library cache lock的方法:
- analyze system state dump: 我们可以通过systemstate事件,来查看所有oracle 进程的信息。这些信息当中包括某个特殊进程的请求/等待资源的信息
ALTER SESSION SET EVENTS 'IMMEDIATE TRACE NAME SYSTEMSTATE LEVEL 10'; 我们到trace文件中,去查找等待进程的pid,观看该进程的等待信息:
PROCESS 8:
----------------------------------------
SO: 50050b08, type: 1, owner: 0, flag: INIT/-/-/0x00
(process) Oracle pid=8, calls cur/top: 5007bf6c/5007bf6c, flag: (0) -
int error: 0, call error: 0, sess error: 0, txn error 0
(post info) last post received: 82 0 4
last post received-location: kslpsr
last process to post me: 5004ff08 1 2
last post sent: 0 0 13
last post sent-location: ksasnd
last process posted by me: 5004ff08 1 2
(latch info) wait_event=0 bits=0
Process Group: DEFAULT, pseudo proc: 50058ac4
O/S info: user: daemon, term: pts/1, ospid: 15161
OSD pid info: 15161
----------------------------------------
SO: 5005f294, type: 3, owner: 50050b08, flag: INIT/-/-/0x00
(session) trans: 0, creator: 50050b08, flag: (41) USR/- BSY/-/-/-/-/-
DID: 0001-0008-00000002, short-term DID: 0000-0000-00000000
txn branch: 0
oct: 6, prv: 0, user: 41/LC
O/S info: user: daemon, term: pts/1, ospid: 15160, machine: goblin.forgotten.realms
program: sqlplus@goblin.forgotten.realms (TNS V1-V3)
application name: SQL*Plus, hash value=3669949024
waiting for 'library cache lock' blocking sess=0x0 seq=253 wait_time=0
!>> handle address=5023ef9c, lock address=5019cad4, 10*mode+namespace=15
Using the 'handle address' you can look up the process that is keeping a lock
on your resource by doing a search on the address within the same tracefile.
Example output:
PROCESS 9:
----------------------------------------
SO: 50050e08, type: 1, owner: 0, flag: INIT/-/-/0x00
(process) Oracle pid=9, calls cur/top: 5007bbac/5007bbfc, flag: (0) -
int error: 0, call error: 0, sess error: 0, txn error 0
....
----------------------------------------
SO: 5019d5e4, type: 34, owner: 5015f65c, flag: INIT/-/-/0x00
!>> LIBRARY OBJECT PIN: pin=5019d5e4 handle=5023ef9c mode=X lock=0
user=5005fad4 session=5005fad4 count=1 mask=0511 savepoint=118218 flags=[00]
这样我就可以看到,pid 9 以独占方式锁住了一个资源,而pid 8在等待。那我们就可以根据v$process、v$session来查询该session的情况,必要时可以杀掉
- 检查X$KGLLK 系统表 该系统表显示的是所有请求/持有 library cache lock的session信息,比v$lock表的信息要详细很多。该表的主要字段含义如下: KGLLKSES session的id号; KGLNAOBJ object的名称; KGLLKHDL object的物理地址;KGLLKREQ 请求它持有锁的数量; 我们可以获得所有的堵塞进程,从而可以杀掉他们:
In the same way we can also find all the blocked sessions:
SELECT SID,USERNAME,TERMINAL,PROGRAM FROM V$SESSION
WHERE SADDR in
(SELECT KGLLKSES FROM X$KGLLK LOCK_A
WHERE KGLLKREQ > 0
AND EXISTS (SELECT LOCK_B.KGLLKHDL FROM X$KGLLK LOCK_B
WHERE KGLLKSES = 'saddr_from_v$session' /* BLOCKING SESSION */
AND LOCK_A.KGLLKHDL = LOCK_B.KGLLKHDL
AND KGLLKREQ = 0)
);
一个解决案例:
- 用户报desc table_name 出错,所有跟该表有关系的语句都不能执行
- 查看系统的锁信息,没有任何信息:select * from v$lock where block=1;
- 查询v$session_wait发现32号session有大量的 library chace lock 等待事件
- 对32号session 进行跟踪:exec dbms_system.set_ev(32,27506,10046,12,'');
- 查看那些表被那些sid锁住了:select * from v$lock_object;
- 根据5步获得的sid,获得锁住object的pid
- 杀掉6步获得的pid
- 发现是使用TOAD工具,该工具在浏览系统结构,并且长时间inactive而造成的