在多个表中加载单个文件时SQL加载器中的死锁

时间:2015-02-12 09:49:13

标签: oracle sql-loader

使用SQL loader将单个文件加载到多个表中时,我们收到以下错误:

SQL*Loader-961: Error calling once/load finishing for table TABLE15
ORA-00604: error occurred at recursive SQL level 1
ORA-00060: deadlock detected while waiting for resource
SQL*Loader-2026: the load was aborted because SQL Loader cannot continue.

我迄今为止尝试过的信息和事情:

  • SQL加载器exe是从.NET Windows服务启动的,但是服务在等待exe完成时什么都不做。
  • Oracle 12c数据库。
  • TABLE15(以及任何其他导入表)上的唯一约束和索引是ID列上的主键+索引。这些是非常基本的'临时的'表,仅用于批量导入数据。业务逻辑,记录有问题的数据并更新最终的'来自'临时'的表格事后发生了。
  • 我们只在我们的一个测试环境(数据库的功能不如生产)中得到此错误,但同样的文件在生产和其他测试环境中导入得很好。
  • 即使确保SQL加载器exe是访问数据库的唯一进程,导入仍然失败,因此看起来SQL加载器正在产生自己的死锁。
  • 该文件包含少于35000条记录(csv文件略低于2kb),超过95%的记录用于TABLE15。我们有更大的文件导入得很好,但是那些导入单个文件到单个表中。
  • 如果我将文件分成两个文件,一个包含TABLE15的数据,另一个包含其他数据,两个文件都处理得很好。单个文件总是失败并分成两个文件,它总是成功。
  • 如果我更改控制文件并将TABLE15部分移动到文件的开头,则会抛出相同的错误,但是在TABLE10上(而不是控制文件)。
  • 如果我将文件分成两个大致相同的文件,那么只有以TABLE15数据开头的文件(原始文件按顺序包含不同的类型)才会在TABLE15死锁上失败(当它们稍微大一点时略小的文件)。
  • 如果我将TABLE15数据放在单个导入文件的末尾,则会在TABLE15死锁上失败。

控制文件如下所示:

OPTIONS (SKIP=1)
LOAD DATA
  INFILE *  
  INTO TABLE TABLE01 WHEN TYPE = 'TYPE01'
  FIELDS TERMINATED BY ","
  OPTIONALLY ENCLOSED BY '"'
  TRAILING NULLCOLS
    ( ID DECIMAL EXTERNAL,
      TABLE01_COL1 CHAR, 
      TABLE01_COL2 CHAR "TRIM(:TABLE01_COL2)",
      TABLE01_COL3 CHAR,
      TYPE FILLER
    )  
  INTO TABLE TABLE02 WHEN TYPE = 'TYPE02'
  FIELDS TERMINATED BY ","
  OPTIONALLY ENCLOSED BY '"'
  TRAILING NULLCOLS
    ( ID DECIMAL EXTERNAL,
      TABLE02_COL1 CHAR, 
      TABLE02_COL2 CHAR "TRIM(:TABLE02_COL2)",
      TABLE02_COL3 CHAR,
      TYPE FILLER
    )
  [...]
  INTO TABLE TABLE17 WHEN TYPE = 'TYPE17'  FIELDS TERMINATED BY ","
  OPTIONALLY ENCLOSED BY '"'
  TRAILING NULLCOLS
    ( ID DECIMAL EXTERNAL,
      TABLE17_COL1 CHAR, 
      TABLE17_COL2 CHAR "TRIM(:TABLE17_COL2)",
      TABLE17_COL3 CHAR,
      TYPE FILLER
    )

有谁知道这个问题的根源是什么(以及如何解决)?据我所知,它似乎是文件大小,多表导入和功能不太强大的数据库的某种组合。

1 个答案:

答案 0 :(得分:1)

您必须联系DBA并请求死锁报告跟踪文件。每当发生死锁时都会生成此文件。没有这个文件,没有人可以帮助你。

PS:我已经看到了单个数据库连接导致数据库死锁的情况。由于性能问题某种"内部超时"中断的SQL插入和此问题被报告为死锁。死锁报告中只有一个会话,锁的类型与通常的不同(SX,SSX,TX)。