来自:http://blog.itpub.net/26015009/viewspace-1074535/
朋友的应用程序在年度结转时调用存储过程时hang住了.经过调试存储过程发现执行到下面的语句时被hang住.
UPDATE t_config_info
SET last_do_time = systimestamp
WHERE config_id = config_record.config_id;
IF SQL%ROWCOUNT = 0 THEN
RAISE error1;
END IF;
解决这个问题的方法就是找到执行存储过程的会话,并用oradebug来dump进程信息.先执行下面的语句来找到执行存储过程会话对应的spid.
SQL>select p.spid
from v$session s,v$process p,v$sqlarea c
where s.username is not null and s.PADDR=p.ADDR and s.sql_id=c.sql_id
and s.sql_fulltext like'%UPDATE t_config_info%'
SPID
----------
14483524
得到的spid为14483524
在另一个会话中执行下面的语句
SQL> oradebug setospid 14483524
Statement processed.
SQL> oradebug unlimit
Statement processed.
SQL> oradebug dump processstate 10
Statement processed.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/hygeia/hygeia1/trace/hygeia2_ora_14483524.trc
从得到的跟踪文件中可以看到以下信息:
SO: 0x700000758606100, type: 4, owner: 0x70000075c4e73e0, flag: INIT/-/-/0x00 if: 0x3 c: 0x3
proc=0x70000075c4e73e0, name=session, file=ksu.h LINE:11467 ID:, pg=0
(session) sid: 539 ser: 14973 trans: 0x700000753a47aa8, creator: 0x70000075c4e73e0
flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40008) -/-
DID: , short-term DID:
txn branch: 0x0
oct: 6, prv: 0, sql: 0x7000005cced65d0, psql: 0x70000076ed6dc58, user: 123/ZWJH_MM
ksuxds FALSE at location: 0
service name: hygeia
client details:
O/S info: user: Administrator, term: LENOVO-JGXROLVS, ospid: 6608:6612
machine: WORKGROUP\LENOVO-JGXROLVS program: plsqldev.exe
application name: PL/SQL Developer, hash value=1190136663
action name: SQL Window - New, hash value=3399691616
Current Wait Stack:
0: waiting for 'enq: TX - row lock contention'
name|mode=0x54580006, usn<<16 | slot=0x15000b, sequence=0x362616
wait_id=811 seq_num=812 snap_id=1
wait times: snap=29.036136 sec, exc=29.036136 sec, total=29.036136 sec
wait times: max=infinite, heur=29.036136 sec
wait counts: calls=59 os=59
in_wait=1 iflags=0x15a0
There is at least one session blocking this session.
Dumping 1 direct blocker(s):
inst: 1, sid: 625, ser: 53645
Dumping final blocker:
inst: 1, sid: 625, ser: 53645
上面的inst: 1, sid: 625, ser: 53645可以知道造成阻塞的会话是1号实例中的会话sid,serial#为625,53645,被人为的kill掉了,然后后继多次执行这个存储过程当hang住后又kill掉了,找到阻塞的会话也知道问题产生的原因了问题也就解决了.