上午开发人员反映说,一个存储过程编译时马上就没有响应了,自己尝试打开存储过程编译
也是一样的提示,就想到是这个过程发生死锁了。
查看dba_ddl_locks 字典,可以看到该过程的锁定信息。
SQL> select * from dba_ddl_locks WHERE OWNER='GUANGZHOU';
SESSION_ID OWNER NAME TYPE
---------- ----------------------- -------------------------------- --------------
109 GUANGZHOU P_UNCREATECONSUMEBILL Table/Procedure/Type
103 GUANGZHOU GUANGZHOU 18
137 GUANGZHOU GUANGZHOU 18
109 GUANGZHOU GUANGZHOU 18
137 GUANGZHOU P_CREATECONSUMEBILL Table/Procedure/Type
109 GUANGZHOU P_CREATECONSUMEBILL Table/Procedure/Type
6 rows selected
考虑到这个过程每日有运行着自动任务。 查看job字典可以看到相关运行的任务。
发现87任务并不在当前时间段运行,排除这个的可能性。
SQL> select * from dba_jobs_running;
SID JOB FAILURES LAST_DATE LAST_SEC THIS_DATE IS_SEC
---------- ---------- ---------- ----------- ---------------- ----------- --
137 87 0 2010-06-25 16:59:44 2010-06-25 17:59:45 0
SQL> select * from dba_jobs;
JOB LOG_USER PRIV_USER SCHEMA_USER LAST_DATE LAST_SEC
---------- ------------------------------ ------------------------------ -----
27 SYS WKSYS WKSYS 2010-06-27 01:00:01
26 SYS WKSYS WKSYS 2010-06-30 10:00:01
66 SYS SYS SYS 2010-06-29 22:00:00
4001 SYS FLOWS_030000 FLOWS_030000 2010-06-30 02:19:00
4002 SYS FLOWS_030000 FLOWS_030000 2010-06-30 09:59:16
46 SYSMAN SYSMAN SYSMAN 2010-06-30 10:06:56
86 GUANGZHOU GUANGZHOU GUANGZHOU 2010-06-30 10:01:16
87 GUANGZHOU GUANGZHOU GUANGZHOU 2010-06-25 16:59:44
8 rows selected
查看等待事件:,可以看到sid=137 的用户有等待事件。
SQL> select * from v$session_wait where WAIT_CLASS#<>6;
SID SEQ# EVENT P1TEXT
---------- ---------- ------------------------------------- --
137 10871 SQL*Net message from dblink driver id
查看这个sid的用户信息。
SQL> select sid,username,serial# from v$session where SID='137';
SID USERNAME SERIAL#
---------- ------------------------------ ----------
137 GUANGZHOU 527
1 rows selected
尝试杀掉该用户的进程,运行下面的命令后很长时间没有相应,只能结束任务。
SQL> alter system kill session '109,213';
alter system kill session '109,213'
ORA-01013: 用户请求取消当前的操作
再次查看这个sid的用户信息。可以看到进程已经被杀掉了,但资源没有释放出来。
SQL> select sid,username,serial# from v$session where SID='137';
SID USERNAME SERIAL# STATUS
---------- ------------------------------ ---------------------------
137 GUANGZHOU 527 KILLED
在操作系统级来kill这些进程. 但是由于此时v$session.paddr已经改变,
无法通过v$session和v$process关联来获得spid。
这时可以使用下面的查询得到addr地址:
2 x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP,
3 decode(bitand (x.ksuprflg,2),0,null,1)
4 FROM x$ksupr x,v$session s
5 WHERE s.paddr(+)=x.addr and s.USERNAME='GUANGZHOU'
6 and bitand(ksspaflg,1)!=0;
USERNAME STATUS SID SERIAL# ADDR KSLLAPSC KSLLAPSN
------------------------------ -------- ---------- ---------- -------------
GUANGZHOU INACTIVE 103 28929 482CD448 1 25 5192
GUANGZHOU ACTIVE 137 527 482D40B8 241 25 5192
GUANGZHOU INACTIVE 101 3559 482D76F0 1 25 5192
GUANGZHOU KILLED 109 213 482DA250 1 25 5192
现在我们获得了进程地址,就可以在v$process中找到spid,
然后可以使用Kill或者orakill在系统级来杀掉这些进程.
SQL> SELECT * FROM V$PROCESS WHERE ADDR='482DA250';
ADDR PID SPID USERNAME SERIAL# TERMINAL PROGRAM
-------- -------- --------------- ---------- ----------- ---------------
482DA250 50 1880 SYSTEM 6 MID-TEST ORACLE.EXE (SHAD)
在服务器上杀掉操作系统级进程就可以了。
C:\Documents and Settings\Administrator>ORAKILL GZTEST 1880
Kill of thread id 1880 in instance GZTEST successfully signalled.
再次查看时,该进程的信息就被杀掉了。
SQL> SELECT * FROM V$PROCESS WHERE ADDR='482DA250';
ADDR PID SPID USERNAME SERIAL# TERMINAL PROGRAM
-------- ---------- ------------------------ --------------- ----------
参考文章:
http://www.ddway.com/ShowDetail_31558.aspx
http://hi.baidu.com/firefly5002/blog/item/c64ed21fd586cbff1ad57652.html