我有以下查询:
select col from tbl where id in (....) for update
所以这个查询从表中选择一些行并锁定它们。
其中一些行被其他客户端锁定(Sql Developer
,如果这很重要),因此此查询阻止等待sql开发人员释放锁定的行。
经过一段时间(约2小时),执行第一次查询的会话得到ORA-01002: fetch out of sequence exception
。我检查了跟踪文件,oracle将这种情况视为死锁。
在跟踪文件中,我找到了以下
DUMP LOCAL BLOCKER: initiate state dump for TIMEOUT
因此,似乎存在一些锁定超时,之后它们被视为死锁。我可以配置吗?
跟踪文件
*** 2013-09-06 15:32:07.204
*** SESSION ID:(971.57585) 2013-09-06 15:32:07.204
*** CLIENT ID:() 2013-09-06 15:32:07.204
*** SERVICE NAME:(asd) 2013-09-06 15:32:07.204
*** MODULE NAME:(JDBC Thin Client) 2013-09-06 15:32:07.204
*** ACTION NAME:() 2013-09-06 15:32:07.204
DUMP LOCAL BLOCKER/HOLDER: block level 5 res [0x60004][0x2729b9],[TX][ext 0x2,0x0]
----------resource 0x85e8435c0----------------------
resname : [0x60004][0x2729b9],[TX][ext 0x2,0x0]
hash mask : x3
Local inst : 2
dir_inst : 2
master_inst : 2
hv idx : 17
hv last r.inc : 54
current inc : 54
hv status : 0
hv master : 0
open options : dd
grant_bits : KJUSERNL KJUSEREX
grant mode : KJUSERNL KJUSERCR KJUSERCW KJUSERPR KJUSERPW KJUSEREX
count : 1 0 0 0 0 1
val_state : KJUSERVS_NOVALUE
valblk : 0x2000483508000000b01e483508000000 H5H5
access_inst : 2
vbreq_state : 0
state : x0
resp : 0x85e8435c0
On Scan_q? : N
Total accesses: 3589
Imm. accesses: 3151
Granted_locks : 1
Cvting_locks : 1
value_block: 20 00 48 35 08 00 00 00 b0 1e 48 35 08 00 00 00
GRANTED_Q :
lp 0x853b8d380 gl KJUSEREX rp 0x85e8435c0 [0x60004][0x2729b9],[TX][ext 0x2,0x0]
master 2 gl owner 0x85d645fc8 possible pid 17202 xid 45000-0002-000019AC bast 0 rseq 46 mseq 0 history 0x14951495
open opt KJUSERDEADLOCK
CONVERT_Q:
lp 0x853b8d8f0 gl KJUSERNL rl KJUSEREX rp 0x85e8435c0 [0x60004][0x2729b9],[TX][ext 0x2,0x0]
master 2 gl owner 0x85d63d0e8 possible pid 17571 xid 65000-0002-00001383 bast 0 rseq 46 mseq 0 history 0x1495149a
convert opt KJUSERGETVALUE
----------enqueue 0x853b8d380------------------------
lock version : 987233
Owner inst : 2
grant_level : KJUSEREX
req_level : KJUSEREX
bast_level : KJUSERNL
notify_func : (nil)
resp : 0x85e8435c0
procp : 0x8523993e8
pid : 17571
proc version : 281
oprocp : (nil)
opid : 17571
group lock owner : 0x85d645fc8
possible pid : 17202
xid : 45000-0002-000019AC
dd_time : 0.0 secs
dd_count : 0
timeout : 0.0 secs
On_timer_q? : N
On_dd_q? : N
lock_state : GRANTED
ast_flag : 0x0
Open Options : KJUSERDEADLOCK
Convert options : KJUSERNOQUEUE KJUSERNODEADLOCKWAIT
History : 0x14951495
Msg_Seq : 0x0
res_seq : 46
valblk : 0x68f4c180ff7f00000100000000000000 h
user session for deadlock lock 0x853b8d380
sid: 965 ser: 10351 audsid: 13432555 user: 500/asd
flags: (0x8100045) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
flags2: (0x40009) -/-/INC
pid: 69 O/S info: user: oracle, term: UNKNOWN, ospid: 17202
image: oracle@asd
client details:
O/S info: user: jboss, term: unknown, ospid: 1234
machine: asd.asd.com program: JDBC Thin Client
application name: JDBC Thin Client, hash value=2546894660
current SQL:
<sql query omitted>
DUMP LOCAL BLOCKER: initiate state dump for TIMEOUT
possible owner[69.17202] on resource TX-00060004-002729B9
*** 2013-09-06 15:32:07.204
Submitting asynchronized dump request [28]. summary=[ges process stack dump (kjdglblkrdm1)].
答案 0 :(得分:2)
我没有看到任何表明Oracle将这种情况视为僵局的事情。如果Oracle发现存在死锁,则会引发ORA-00060错误并产生死锁跟踪文件。
默认情况下,Oracle将允许简单的阻塞锁永久阻止,而不会终止阻止程序或服务器。但是,您可以通过使用WAIT
子句来控制等待多长时间。例如
select col
from tbl
where id in (....)
for update wait 30
指定您要等待最多30秒才能锁定行。如果之后行保持锁定,则会收到ORA-30006错误“资源忙;获取WAIT超时已到期”。
我的猜测是,您看到的行为表明您的DBA已使用Oracle Resource Manager to configure a resource plan that kills idle blockers after a specified length of time。您可以与DBA讨论如何更改该计划,但如果您发现您希望不同的查询和不同的应用程序具有不同的超时,则通常会更复杂且更难以微调。