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

Posted

技术标签:

【中文标题】问题从 oracle 跟踪文件中查找死锁错误的原因【英文标题】:Issue Finding cause of deadlock error from oracle trace file 【发布时间】:2017-09-06 09:24:31 【问题描述】:

我正在使用多个客户端测试一个应用程序。在某些时候,我在数据库中遇到了死锁。我得到以下痕迹:

引起:com.indra.davinci.common.dataaccess.DataAccessException: SQL:DELETE FROM EMPLOYEE WHERE DEPT_ID IN (SELECT ID FROM DPTO WHERE COMPANY_ID = ?),参数:[409386]

原因:java.sql.SQLException: ORA-00060: deadlock detected while 等待资源

表 EMPLOYEE 有两个子表(MANAGER 和 DEVELOPER),它们都具有 EMPLOYEE 的外键。我已经为外键创建了索引。 未设置级联删除。另一方面,应用程序的代码执行以下操作: 1. 删除子表 MANAGER 中属于具体 EMPLOYEE 的行。 2. 删除子表 DEVELOPER 中属于具体 EMPLOYEE 的行。 3. 删除 EMPLOYEE 表中的行。 4.删除DPTO表中的行(EMPLOYEE是DPTO的子表,有外键和索引)。

我在应用程序中设置了跟踪以获取请求的性能顺序,我看到以下内容:

06/09/2017 08:43:13.539 初始化删除管理器客户端:409383

06/09/2017 08:43:13.539 初始化删除管理器客户端:409386

06/09/2017 08:43:13.555 END DELETE MANAGER 客户端:409386

06/09/2017 08:43:13.555 初始化删除开发者客户端:409386

06/09/2017 08:43:13.555 END DELETE MANAGER 客户端:409383

06/09/2017 08:43:13.555 初始化删除开发者客户端:409383

06/09/2017 08:43:13.555 END DELETE 开发者客户端:409386

06/09/2017 08:43:13.555 初始化删除员工客户端:409386

06/09/2017 08:43:13.555 END DELETE DEVELOPER 客户端:409383

06/09/2017 08:43:13.555 初始化删除员工客户端:409383

06/09/2017 08:43:13.555 初始化删除管理器客户端:409389

06/09/2017 08:43:13.570 初始化删除管理器客户端:409407

06/09/2017 08:43:13.570 END DELETE MANAGER 客户端:409389

06/09/2017 08:43:13.570 初始化删除开发者客户端:409389

06/09/2017 08:43:13.570 END DELETE DEVELOPER 客户端:409389

06/09/2017 08:43:13.570 初始化删除员工客户端:409389

06/09/2017 08:43:13.570 END DELETE MANAGER 客户端:409407

06/09/2017 08:43:13.570 初始化删除开发者客户端:409407

06/09/2017 08:43:13.570 END DELETE DEVELOPER 客户端:409407

06/09/2017 08:43:13.570 初始化删除员工客户端:409407

似乎在 08:43:13.555 瞬间有两个客户端试图从 EMPLOYEE 表中删除。

我在 Oracle 的跟踪文件中得到以下信息:

Trace file C:\ORACLEXE\APP\ORACLE\diag\rdbms\xe\xe\trace\xe_ora_10068.trc
Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
Windows NT Version V6.1 Service Pack 1 
CPU                 : 4 - type 586, 2 Physical Cores
Process Affinity    : 0x0x00000000
Memory (Avail/Total): Ph:2347M/16247M, Ph+PgF:15271M/32493M, VA:2685M/4095M 
Instance name: xe
Redo thread mounted by this instance: 1
Oracle process number: 36
Windows thread id: 10068, image: ORACLE.EXE (SHAD)


*** 2017-09-06 08:43:16.613
*** SESSION ID:(11.369) 2017-09-06 08:43:16.613
*** CLIENT ID:() 2017-09-06 08:43:16.613
*** SERVICE NAME:(XE) 2017-09-06 08:43:16.613
*** MODULE NAME:(JDBC Thin Client) 2017-09-06 08:43:16.613
*** ACTION NAME:() 2017-09-06 08:43:16.613



*** 2017-09-06 08:43:16.613
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-0008747d-00000000        36      11    SX   SSX       32      10    SX   SSX
TM-0008747d-00000000        32      10    SX   SSX       36      11    SX   SSX

session 11: DID 0001-0024-00000114  session 10: DID 0001-0020-0000001C 
session 10: DID 0001-0020-0000001C  session 11: DID 0001-0024-00000114 

Rows waited on:
  Session 11: no row
  Session 10: no row

----- Information for the OTHER waiting sessions -----
Session 10:
  sid: 10 ser: 27 audsid: 14562964 user: 184/USRPLNADIF
    flags: (0x41) USR/- flags_idl: (0x1) BSY/-/-/-/-/-
    flags2: (0x40009) -/-
  pid: 32 O/S info: user: SYSTEM, term: MARRIETAW7, ospid: 13724
    image: ORACLE.EXE (SHAD)
  client details:
    O/S info: user: marrieta, term: unknown, ospid: 1234
    machine: marrietaw7 program: JDBC Thin Client
    application name: JDBC Thin Client, hash value=2546894660
  current SQL:
  DELETE FROM EMPLOYEE WHERE DEPT_ID IN (SELECT ID FROM DPTO WHERE COMPANY_ID = :1)

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

Information for THIS session:

----- Current SQL Statement for this session (sql_id=6v66dbfh41hbx) -----
DELETE FROM EMPLOYEE WHERE DEPT_ID IN (SELECT ID FROM DPTO WHERE COMPANY_ID = :1)

对可能发生的事情有什么想法吗?

谢谢。

【问题讨论】:

【参考方案1】:

好吧,我已经检查了跟踪文件中的死锁图,具体来说就是这部分:

Deadlock graph:
                       ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TM-0008747d-00000000        36      11    SX   SSX       32      10    SX   SSX
TM-0008747d-00000000        32      10    SX   SSX       36      11    SX   SSX

我将十六进制的 0008747d 转换为十进制并执行如下:

SELECT * FROM dba_objects WHERE object_id= 554109;

我得到了阻塞数据库的表。该表不被应用程序使用,而是在数据库中创建(可能在它使用的应用程序的旧版本中),我发现该表是 EMPLOYEE 的子表,并且没有 FK 的索引。我会尝试解决这个问题,我会发表评论。

【讨论】:

是的,未索引的外键通常是死锁的原因

以上是关于问题从 oracle 跟踪文件中查找死锁错误的原因的主要内容,如果未能解决你的问题,请参考以下文章

Oracle数据库死锁问题,高分悬赏答案

SQL Server 事务 (ID) 死锁

ASP.NET - 部署问题 - 通过 Web.Config 启用堆栈跟踪/跟踪侦听器日志以查找内部服务器 500 错误的原因

500分悬赏oracle死锁问题解决,决不食言

使用 ODBC Trace 或 Oracle Trace 查找错误原因?

查找Java应用程序死锁原因的工具[关闭]