Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

133

积分

0

好友

17

主题
1#
发表于 2013-11-18 17:26:26 | 查看: 3703| 回复: 7
本帖最后由 saup007 于 2013-11-18 17:27 编辑
  1. 现在业务遇到二种情况的死锁,很奇怪。这个问题困惑很久了。

  2. 这二张表,没有主外键关系。

  3. 1、update和insert产生死锁

  4. 我知道insert,主键重复覆盖会产生死锁,但update和insert怎么产生的死锁呢?

  5. SQL1:
  6. update table1 set ... where ...

  7. SQL2:
  8. insert into table2 values(......)

  9. Deadlock graph:
  10.                        ---------Blocker(s)--------  ---------Waiter(s)---------
  11. Resource Name          process session holds waits  process session holds waits
  12. TX-003f0006-000619e2       566    1739     X            478    1749           X
  13. TX-00160000-00117cf1       478    1749     X            566    1739           S

  14. session 1739: DID 0001-0236-0000CB67    session 1749: DID 0001-01DE-00014EA2
  15. session 1749: DID 0001-01DE-00014EA2    session 1739: DID 0001-0236-0000CB67


  16. --insert与insert产生死锁,但update和insert怎么会产生死锁,不知道。
  17. CREATE TABLE T1 (col1 NUMBER NOT NULL, col2 NUMBER);
  18. ALTER TABLE T1 ADD CONSTRAINT T1_UNIQUE UNIQUE (col1, col2);

  19. session1> INSERT INTO T1 VALUES (1, NULL);
  20. session2> INSERT INTO T1 VALUES (2, NULL);
  21. session2> INSERT INTO T1 VALUES (1, NULL); -- <= this will wait on session1
  22. session1> INSERT INTO T1 VALUES (2, NULL); -- <= Deadlock !



  23. 2、两张没有主外键的表,也有死锁

  24. 通过deadlock graph,只能找到导致deadlock的一条数据,但怎么产生的没有头绪。。

  25. SQL1:
  26. select * from table1 where ... for update;

  27. SQL2:
  28. update table2 set ... where ... RETURNING...

  29. deadlock graph:
  30.                        ---------Blocker(s)--------  ---------Waiter(s)---------
  31. Resource Name          process session holds waits  process session holds waits
  32. TX-002a0013-000b7c02       564    1246     X            268    1160           X
  33. TX-002c001b-000a3411       268    1160     X            564    1246           X

  34. session 1246: DID 0001-0234-00001EC4    session 1160: DID 0001-010C-00128EE3
  35. session 1160: DID 0001-010C-00128EE3    session 1246: DID 0001-0234-00001EC4

  36. Rows waited on:
  37.   Session 1246: obj - rowid = 00038F03 - AAA48DAAeAABECqAAw
  38.   (dictionary objn - 233219, file - 30, block - 278698, slot - 48)
  39.   Session 1160: obj - rowid = 00039287 - AAA5KHAAgAAAJcQAC4
  40.   (dictionary objn - 234119, file - 32, block - 38672, slot - 184)
复制代码
2#
发表于 2013-11-18 18:40:39
ORA-60 有trace 的,给出完整trace

回复 只看该作者 道具 举报

3#
发表于 2013-11-19 10:17:18
Maclean Liu(刘相兵 发表于 2013-11-18 18:40
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_trace.rar

899.39 KB, 下载次数: 892

回复 只看该作者 道具 举报

4#
发表于 2013-11-19 15:20:43
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

回复 只看该作者 道具 举报

5#
发表于 2013-11-19 16:02:08
Maclean Liu(刘相兵 发表于 2013-11-19 15:20
Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Reso ...
  1. 15:49:15 saup@TEST11G> select * from t1;

  2.       COL1         COL2
  3. ---------- ----------
  4.          1
  5.          2

  6. 15:49:19 saup@TEST11G>
  7. 15:49:23 saup@TEST11G> select * from t2;

  8.        ID1          ID2
  9. ---------- ----------
  10.          1            1
  11.          1            2
  12.          2            1
  13.          2            2
  14. session 1:
  15. 15:49:40 saup@TEST11G> select * from t1 where col1=1 for update;

  16.       COL1         COL2
  17. ---------- ----------
  18.          1

  19. session 2
  20. 15:49:57 saup@TEST11G> update t2 set id2=100 where id1=1;

  21. 2 rows updated.

  22. session 1
  23. 15:52:33 saup@TEST11G> update t2 set id2=100 where id1=1;
  24. update t2 set id2=100 where id1=1

  25. (在session 2执行完后,deadlock)

  26. session 2:

  27. 15:50:17 saup@TEST11G>  select * from t1 where col1=1 for update;

  28.       COL1         COL2
  29. ---------- ----------
  30.          1

复制代码
除了主外键,二张表deadlock还可以这样。

回复 只看该作者 道具 举报

6#
发表于 2013-11-19 16:14:50
saup007 发表于 2013-11-19 16:02
除了主外键,二张表deadlock还可以这样。

你给的例子比 主外键的例子更常见吧?

ocp课程介绍的死锁 就是这种最简单的啊

回复 只看该作者 道具 举报

7#
发表于 2013-11-19 16:16:59
本帖最后由 saup007 于 2013-11-19 16:20 编辑

t1 表中 col1、col2 是主键,具有唯一性


  1. --session 1

  2. insert into t1 values(3,null);

  3. --session 2

  4. update t2 set id2=200 where id1=1

  5. --session 2 -- 被阻塞住,在下面session 2执行完后,此处死锁

  6. insert into t1 values(3,null);

  7. --session 1 -- 被session 2阻塞

  8. update t2 set id2=200 where id1=1;



复制代码

回复 只看该作者 道具 举报

8#
发表于 2013-11-19 16:21:48
Maclean Liu(刘相兵 发表于 2013-11-19 16:14
你给的例子比 主外键的例子更常见吧?

ocp课程介绍的死锁 就是这种最简单的啊 ...

我脑盘筋没转过来弯。。。没想通。。不知怎么的,就是绕不过来。现在明白了。

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-6-15 02:08 , Processed in 0.054278 second(s), 24 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569