使用SQL加载器将单个文件加载到多个表中时,我们会收到以下错误:
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窗口服务启动的,但该服务在等待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
)
有人知道这个问题的根源是什么(以及如何解决)吗?据我所知,这似乎是文件大小、多表导入和功能较弱的数据库的某种组合。
您必须联系DBA并请求死锁报告跟踪文件。每当发生死锁时,都会生成此文件。没有这个文件没有人能帮你。
PS:我已经看到过单个数据库连接导致数据库死锁的情况。由于性能问题,某种"内部超时"中断了SQL插入,此问题被报告为死锁。死锁报告中只有一个会话,并且锁的类型与通常的不同(SX、SSX、TX)。