从oracle跟踪文件中查找死锁错误的原因

时间:2013-06-28 05:54:28

标签: oracle deadlock trace

当多个用户正在使用该应用程序时,我的应用程序中经常出现这种“等待资源时检测到ora-00060死锁”的错误。我从oracle Admin获得了跟踪文件,但需要帮助才能阅读它。下面是跟踪文件中的一些数据,我希望这有助于找到原因。

*** 2013-06-25 09:37:35.324
DEADLOCK DETECTED ( ORA-00060 )

[Transaction Deadlock]

The following deadlock is not an ORACLE error. It is a deadlock due 
to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:

Deadlock graph:
                   ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

session 72: DID 0001-00D2-000000C6  session 24: DID 0001-00D0-00000043 
session 24: DID 0001-00D0-00000043  session 72: DID 0001-00D2-000000C6 

Rows waited on:
 Session 72: no row
 Session 24: no row

----- Information for the OTHER waiting sessions -----
Session 24:
 sid: 24 ser: 45245 audsid: 31660323 user: 90/USER
  flags: (0x45) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
  flags2: (0x40009) -/-/INC
 pid: 208 O/S info: user: zgrid, term: UNKNOWN, ospid: 2439
   image: oracle@xyz.local
 client details:
   O/S info: user: , term: , ospid: 1234
   machine: xyz.local program: 
 current SQL:
  delete from EMPLOYEE where EMP_ID=:1

 ----- End of information for the OTHER waiting sessions -----

Information for THIS session:

 ----- Current SQL Statement for this session (sql_id=dyfg1wd8xa9qt) -----
 delete from EMPLOYEE where EMP_ID=:1
===================================================

如果有人可以告诉我“死锁图::”的含义,我将不胜感激。在节上等待的行也表示没有行。

我还在一些博客中读到跟踪文件中的“sqltxt”部分可以提示原因。以下是我在该部分中看到的查询。

 select /*+ all_rows */ count(1) from "USERS"."EMPLOYEE_SALARY" where EMPSAL_EMP_ID=:1

employee_salary表在EMPSAL_EMP_ID列上具有外键约束。

sql提示说“all_rows”,这是否意味着当从employee表中删除记录时,此表会获得表级锁定?我目前没有外键列的索引。在此列上添加索引会有帮助吗?

请发布,以防需要更多信息。

由于

1 个答案:

答案 0 :(得分:29)

首先,select语句永远不会锁定Oracle中的任何内容,只使用最后一个可用的一致数据版本。自{6}以来select ... for update之后的update数据锁不是自Oracle 9i以来的情况,但查询中没有for update子句。

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       210      72    SX   SSX      208      24    SX   SSX

会话#72保持具有“行独占”类型(SX)的表级锁(TM)并且想要在同一表上获取“共享行独占”(SSX)锁。会话#24已阻止此会话,该会话已保持相同类型(SX)的表级锁定,并在SSX锁定可用时等待。

Resource Name          process session holds waits  process session holds waits
TM-000151a2-00000000       208      24    SX   SSX      210      72    SX   SSX

这(第二行)演示了完全相同的情况,但反方向:会话#24等待SSX锁定变为可用,但被会话#72阻止,该会话已经在同一个表上保存了SX锁。

因此,Sessions#24和Session#72相互阻塞:发生死锁。

两种锁类型(SX和SSX)都是表级锁 要了解这种情况,我建议您阅读Franck Pachot的this article

以下是本文的引文,与您的情况直接相关(请注意,SSX和SRX缩写是等效的):

  

参照完整性也获得TM锁。例如,常见的   使用未编入索引的外键导致子表上的S锁定时   您在父表上发出删除或更新密钥。这是   因为没有索引,Oracle没有单一的低级资源   锁定以防止可能违反的并发插入   参照完整性。
  当外键列是领先的   常规索引中的列,然后是父项的第一个索引项   value可以用作单个资源,并使用行级TX锁定   锁定。
  如果参照完整性有删除级联怎么办?在   除S模式外,还有意更新中的行   子表,与行X(RX)模式一样。这是共享行的位置   独占(SRX)发生:S + RX = SRX。

因此,最可能的变体是会话#72和会话#24同时删除EMPLOYEE表中的某些行,并且on delete cascade的{​​{1}}约束与缺席相关联EMPSAL_EMP_ID列中的索引,其中EMPLOYEE_SALARY列首先列出。