前言:出现library cache lock,一般是有底层数据结构锁了,为什么会出现这种情况,原因“”很简单,应为有其它事件在获取s或者x锁,这个时候,如果该事件发生事件较长,影响业务了,如何来定位呢?本文介绍一种通用的方法,来发现持有方是谁,找到持有方(一般是不常见的操作),后面有效避开,则可最大限度避免该等待事件出现。
第一步:查ash,看看当时发生了什么
SQL> col WAIT_CLASS for a20
SQL> col PROGRAM for a30
SQL> col EVENT for a30
SQL> col SAMPLE_TIME for a30
SQL> select instance_number,
sample_time,
sql_id,
SQL_PLAN_HASH_VALUE,
program,
event,
SESSION_STATE,
WAIT_TIME,
TIME_WAITED,
wait_class,
BLOCKING_SESSION,
p2,
p3
from dba_hist_active_sess_history
where sample_time between
to_date('2021-xx-20 xx:00', 'yyyy-mm-dd hh24:mi') and
to_date('2021-xx-20 xx:03', 'yyyy-mm-dd hh24:mi')
order by 1, 2;
查询结果如下:

通过图片可以看到:
可以看到sqlid为:6ag2uxc4m1fd8的会话被1058会话阻塞,导致数据库出现“library cache lock”。
按照下一章,继续查找。
第二步:找到包含该事件段的dia0诊断文件,打开后搜索“library cachee lock”
dia0文件位于oracle的trace中,可以ls -lrt dia0 查找,一般不会太多,如果太多。
找到对应时间段的阻塞链:
Chains most likely to have caused the hang:
[a] Chain 1 Signature:
如果多级阻塞,该链条会显示阻塞的完整链条,右边是最外层,一般也就是session等待事件中直观展现出来的。
继续向下阅读,找到Chain 1的详细信息,期中描述了阻塞关系:
Oracle session identified by:
{
instance: 2 (cbsdb.cbsdb2)
os id: 21824476
process id: 185, oracle@cbsdb2
session id: 1380 <=====这个会话,就是被阻塞的我们的业务,即出现'library cache lock'等待的会话
session serial #: 37293
}
is waiting for 'library cache lock' with wait info:
{
p1: 'handle address'=0x700010eb4796968
p2: 'lock address'=0x70001039a764610
p3: '100*mode+namespace'=0x4b90d00010003
.....
p3: ''=0x2000001
}
and is blocked by 《========================可以看到1380被1058阻塞
=> Oracle session identified by:
{
instance: 2 (cbsdb.cbsdb2)
os id: 18612894
process id: 349, oracle@cbsdb2 (TNS V1-V3)
session id: 1058
session serial #: 18162
}
继续往后阅读,阅读到
HM: Short Stack of immediate waiter session ID 1380
HM: Short Stack of root session ID 1058
这一部分有两个会话操作的SQL,根据该SQL,可以知道当时1058在做什么,导致锁的发生。
一般分析表、修改表结构等情况,容易引发这种锁等待。
查到到1058的具体SQL后,DBA可以很容易判别出业务特点,然后避开业务时段操作,解决该问题。
最后:另外一次案例
例如有一次AWR:
,出现大量cursor: pin S wait on X,同时伴有行锁,一般认为行锁是业务问题,确实业务有很大关系,但是如果同样的业务,平日没什么问题,而某个时段出现问题,则可能是底层结构锁导致业务运行时间边长,加剧问题了发生。
我们用上面的方法继续定位,发现:
Chain 1 Signature: 'library cache lock'<='cursor: pin S wait on X'<='enq: TX - row lock contention'
Chain 2 Signature: 'db file scattered read'<='library cache lock'
这样,知道问题由于某个“db file scattered read”引发的,并且肯定是同一张表的操作才会出现这种问题,然后通过dia0文件顺腾摸瓜,结合该事件段内发生的“db file scattered read”等待事件是否涉及同一张表,最后分析区冲突所在即可,通过该方法,最终我们发现同一张表的导出表和分析表在同一时间段内发生,导致S锁与X锁冲突,避开后问题解决。




