奇怪的deadlock -- 死锁
本帖最后由 saup007 于 2013-11-18 17:27 编辑现在业务遇到二种情况的死锁,很奇怪。这个问题困惑很久了。
这二张表,没有主外键关系。
1、update和insert产生死锁
我知道insert,主键重复覆盖会产生死锁,但update和insert怎么产生的死锁呢?
SQL1:
update table1 set ... where ...
SQL2:
insert into table2 values(......)
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-003f0006-000619e2 566 1739 X 478 1749 X
TX-00160000-00117cf1 478 1749 X 566 1739 S
session 1739: DID 0001-0236-0000CB67 session 1749: DID 0001-01DE-00014EA2
session 1749: DID 0001-01DE-00014EA2 session 1739: DID 0001-0236-0000CB67
--insert与insert产生死锁,但update和insert怎么会产生死锁,不知道。
CREATE TABLE T1 (col1 NUMBER NOT NULL, col2 NUMBER);
ALTER TABLE T1 ADD CONSTRAINT T1_UNIQUE UNIQUE (col1, col2);
session1> INSERT INTO T1 VALUES (1, NULL);
session2> INSERT INTO T1 VALUES (2, NULL);
session2> INSERT INTO T1 VALUES (1, NULL); -- <= this will wait on session1
session1> INSERT INTO T1 VALUES (2, NULL); -- <= Deadlock !
2、两张没有主外键的表,也有死锁
通过deadlock graph,只能找到导致deadlock的一条数据,但怎么产生的没有头绪。。
SQL1:
select * from table1 where ... for update;
SQL2:
update table2 set ... where ... RETURNING...
deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-002a0013-000b7c02 564 1246 X 268 1160 X
TX-002c001b-000a3411 268 1160 X 564 1246 X
session 1246: DID 0001-0234-00001EC4 session 1160: DID 0001-010C-00128EE3
session 1160: DID 0001-010C-00128EE3 session 1246: DID 0001-0234-00001EC4
Rows waited on:
Session 1246: obj - rowid = 00038F03 - AAA48DAAeAABECqAAw
(dictionary objn - 233219, file - 30, block - 278698, slot - 48)
Session 1160: obj - rowid = 00039287 - AAA5KHAAgAAAJcQAC4
(dictionary objn - 234119, file - 32, block - 38672, slot - 184) ORA-60 有trace 的,给出完整trace Maclean Liu(刘相兵 发表于 2013-11-18 18:40 static/image/common/back.gif
ORA-60 有trace 的,给出完整trace
给出完整的trace文件了。
ora_31908.trc 这个trace,二种情况的deadlock都在里面,Current SQL 在trace文件后面有insert和update的死锁(110869行)。
ora_31899.trc 这个trace,只有select ... for update 和 update 语句的deadlock。
谢谢。
主要是二张看似没有什么关系的表,也没有主外键关系。 Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-002a000c-000b7ac7 124 1223 X 367 2078 X
TX-0032001d-0006d9a1 367 2078 X 124 1223 X
session 1223: DID 0001-007C-00223740 session 2078: DID 0001-016F-00013484
session 2078: DID 0001-016F-00013484 session 1223: DID 0001-007C-00223740
Rows waited on:
Session 1223: obj - rowid = 00039287 - AAA5KHAAgAAAJcQACo
(dictionary objn - 234119, file - 32, block - 38672, slot - 168)
Session 2078: obj - rowid = 00038F03 - AAA48DAAeAABDTzAAm
(dictionary objn - 233219, file - 30, block - 275699, slot - 38)
LOG_RECORD_DETAIL objn - 233219
LOG_RECORD_IDCARD objn - 234119,
session 2078 先锁住了 LOG_RECORD_IDCARD ,之后尝试锁LOG_RECORD_DETAIL
session 1223 先锁住了 LOG_RECORD_DETAIL ,之后尝试锁 LOG_RECORD_IDCARD
session 2078的SQL执行顺序:
1、 SELECT D.FIRST_LOGIN_TIME, D.ONLINE_SECOND_TOTAL, D.OFFLINE_SECOND_TOTAL, D.USER_COUNT FROM LOG_RECORD_IDCARD D WHERE GAME_ID = :B2 AND ID_CODE = :B1 FOR UPDATE
2、 UPDATE LOG_RECORD_DETAIL SET LOGOUT_TIME = :B1 , ROLE_LEVEL = :B6 , MONEY1 = :B5 , MONEY2 = :B4 , EXPERIENCE = :B3 WHERE LOGIN_ID = :B2 RETURNING SERVER_ID, (:B1 - LOGIN_TIME) * 86400, LOGIN_IP, PROVINCE_CODE, CITY_CODE INTO :O0 ,:O1 ,:O2 ,:O3 ,:O4
session 1223:
1、UPDATE LOG_RECORD_DETAIL SET LOGOUT_TIME = :B1 , ROLE_LEVEL = :B6 , MONEY1 = :B5 , MONEY2 = :B4 , EXPERIENCE = :B3 WHERE LOGIN_ID = :B2 RETURNING SERVER_ID, (:B1 - LOGIN_TIME) * 86400, LOGIN_IP, PROVINCE_CODE, CITY_CODE INTO :O0 ,:O1 ,:O2 ,:O3 ,:O4
2、SELECT D.FIRST_LOGIN_TIME, D.ONLINE_SECOND_TOTAL, D.OFFLINE_SECOND_TOTAL, D.USER_COUNT FROM LOG_RECORD_IDCARD D WHERE GAME_ID = :B2 AND ID_CODE = :B1 FOR UPDATE
Maclean Liu(刘相兵 发表于 2013-11-19 15:20 static/image/common/back.gif
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Reso ...15:49:15 saup@TEST11G> select * from t1;
COL1 COL2
---------- ----------
1
2
15:49:19 saup@TEST11G>
15:49:23 saup@TEST11G> select * from t2;
ID1 ID2
---------- ----------
1 1
1 2
2 1
2 2
session 1:
15:49:40 saup@TEST11G> select * from t1 where col1=1 for update;
COL1 COL2
---------- ----------
1
session 2
15:49:57 saup@TEST11G> update t2 set id2=100 where id1=1;
2 rows updated.
session 1
15:52:33 saup@TEST11G> update t2 set id2=100 where id1=1;
update t2 set id2=100 where id1=1
(在session 2执行完后,deadlock)
session 2:
15:50:17 saup@TEST11G> select * from t1 where col1=1 for update;
COL1 COL2
---------- ----------
1
除了主外键,二张表deadlock还可以这样。 saup007 发表于 2013-11-19 16:02 static/image/common/back.gif
除了主外键,二张表deadlock还可以这样。
你给的例子比 主外键的例子更常见吧?
ocp课程介绍的死锁 就是这种最简单的啊 本帖最后由 saup007 于 2013-11-19 16:20 编辑
t1 表中 col1、col2 是主键,具有唯一性
--session 1
insert into t1 values(3,null);
--session 2
update t2 set id2=200 where id1=1
--session 2 -- 被阻塞住,在下面session 2执行完后,此处死锁
insert into t1 values(3,null);
--session 1 -- 被session 2阻塞
update t2 set id2=200 where id1=1;
Maclean Liu(刘相兵 发表于 2013-11-19 16:14 static/image/common/back.gif
你给的例子比 主外键的例子更常见吧?
ocp课程介绍的死锁 就是这种最简单的啊 ...
我脑盘筋没转过来弯。。。没想通。。不知怎么的,就是绕不过来。现在明白了。
页:
[1]