同事下午做grant 赋权操作,执行如下命令中挂住,等了N长时间也没有执行完毕:
SQL> grant select on UR_USER_INFO tohfyd;
http://blog.csdn.net/tianlesoftware/article/details/7956996
Library Cache lock有3中模式:
(1)Share(S): 当读取一个library cache object的时候获得
(2)Exclusive(X): 当创建/修改一个library cacheobject的时候获得
(3)Null(N): 用来确保对象依赖性
比如一个进程想要编译某个视图,那么就会获得一个共享锁,如果我们要create/drop/alter某个对象,那么就会获得exclusive lock。Null锁非常特殊,我们在任何可以执行的对象(cursor,function)上面都拥有NULL锁,我们可以随时打破这个NULL锁,当 这个NULL锁被打破了,就表示这个对象被更改了,需要从新编译。
NULL锁主要的目的就是标记某个对象是否有效。 比如一个SQL语句在解析的时候获得了NULL 锁,如果这个SQL的对象一直在共享池中,那么这个NULL锁就会一直存在下去,当这个SQL语句所引用的表被修改之后,这个NULL锁就被打破了,因为 修改这个SQL语句的时候会获得Exclusive 锁,由于NULL锁被打破了,下次执行这个SQL的时候就需要从新编译。
等待事件如下:
EVENT COUNT(*)
--------------------------------------------------------------------------
jobq slave wait 1
SQL*Net more data from dblink 1
db file sequential read 2
SQL*Net message to client 1
db file scattered read 1
SQL*Net break/reset to client 1
SQL*Net message from client 238
smon timer 1
pmon timer 1
SQL*Net message fromdblink 4
rdbms ipc message 20
Streams AQ: qmn slave idle wait 1
library cache lock 1
Streams AQ: qmn coordinator idle wait 1
SQL*Net more data to client 1
Streams AQ: waiting for time management orcleanup tasks 1
这里标红了2个地方,后面会具体分析。
SQL> select decode(request, 0, 'Holder:', ' --Waiter:') || s.inst_id || ':'||
2 s.sid || ',' ||s.serial# as sess,
3 l.id1,
4 l.id2,
5 l.lmode,
6 l.request,
7 l.type,
8 l.ctime,
9 s.sql_id,
10 s.event,
11 s.last_call_et
12 from gv$lock l, gv$session s
13 where (id1, id2, l.type) in
14 (select id1, id2, type from gv$lock where request > 0)
15 and l.sid = s.sid
16 and l.inst_id = s.inst_id order by id1,ctime desc,request;
no rows selected
SQL> SELECT s.sid, kglpnmod"Mode", kglpnreq "Req", SPID "OS Process"
2 FROM v$session_wait w, x$kglpnp, v$session s ,v$process o
3 WHERE p.kglpnuse=s.saddr
4 AND kglpnhdl=w.p1raw
5 and w.event like '%librarycache lock%'
6 and s.paddr=o.addr
7 /
SID Mode Req OS Process
---------- ---------- ----------------------
5444 2 0 18645
第二SQL 返回了一个对应的session: 5444。 这里的Mode 2是share模式,如果是3就是Exclusive模式。
进一步查看:
oracle@w25k03da$ora active|grep library
5261 1167 4296 SYS w25k03da library cachelock 66552486656/616245 0 b84sn8gh70cx7
这里的session :5261 是我们执行grant的语句,其对应的等待事件是library cache lock ,该操作已经挂了很长时间。
看一下session: 5444.
oracle@w25k03da$ora active|grep 5444
5444 130 18645 BZYD WORKGROUP\BZYD-7 SQL*Net message from dblink 1413697536/1/0 0328u7k7c5mycu
oracle@w25k03da$ps -ef|grep 18645
oracle 18645 1 0 07:18:49 ? 0:00 oraclewcrma1 (LOCAL=NO)
oracle 8062 8059 0 17:40:39 pts/2 0:00 grep18645
该session 是一个远程的连接。
这里我们做一个hanganalyze 分析,就清楚他们之间到底是什么关系了:
Hanganalyze的用法如下:
$ sqlplus -prelim / as sysdba
SQL>set time on
18:02:57SQL> set timing on
SQL>oradebug setmypid
Statementprocessed.
SQL>alter session set tracefile_identifier='dave';
SQL>oradebugunlimit
SQL>oradebug hanganalyze 3
HangAnalysis in /oracle/admin/bomc/udump/bomc2_ora_1011948.trc
从trace 文件里我们取出关键内容:
State of nodes
([nodenum]/cnode/sid/sess_srno/session/ospid/state/start/finish/[adjlist]/predecessor):
…
[5259]/0/5260/195/0x77d77060/5879/IGN/105/106//none
[5260]/0/5261/1167/0x76da5ea8/4296/NLEAF/107/110/[5443]/none
[5261]/0/5262/78/0x75d9c660/4332/IGN/111/112//none
…
[5442]/0/5443/124/0x76dc8b38/1814/IGN/453/454//none
[5443]/0/5444/130/0x75dbf2f0/18645/LEAF/108/109//5260
[5444]/0/5445/218/0x7fda5440/10872/IGN/455/456//none
…
从这里,我们可以确定:[5443]阻塞了[5260]。导致我们的grant操作一直获取到不到library cache的lock,而处于等待状态。
[5260] 是我们的grant 操作,对应session:5261。
[5443] 对应的就是我们看到的session:5444。
查看session: 5444:
SQL> selectsid,username,status,osuser,machine,program,serial#,terminal from v$sessionwhere sid='5444';
SID USERNAME STATUS OSUSER MACHINE PROGRAM SERIAL# TERMINAL
---------- -------------------------------------- ------------------------------ --------------- ------------------------- ------------------------------
5444 BZYD ACTIVE Administrator WORKGROUP\BZYD- sqlplus.exe 130 BZYD-7D54F1F8A0
7D54F1F8A0
这个是一个个人终端的sqlplus,查看了一下连接时间,早上7:19分连接的,后来一直挂在这。
根据sql_id,从V$SQLTEXT中没有捞到对应的SQL. 同事想了半天,也没能确认这个连接是谁的,无耐把这个session kill 掉了,grant 操作立马完成。
现在想想,应该从dba_hist_sqltext在捞一把,或许就捞到那个SQL了。语句如下:
select sql_text from dba_hist_sqltext wheresql_id='aysann58c69s3';