我有一个每周报告作业,我必须加载大约 48 个日志,每个日志中包含大约 750k 行数据。为了促进这一点,我们一直在使用一个 Java 作业,它将 SQL*Loader 作为外部进程(使用 ProcessBuilder)一个接一个地运行。然而最近,这个进程在加载过程中异常终止,导致表被锁定,基本上导致进程停止,直到我们可以向 DB 团队开票以终止挂起的会话。是否有比使用 SQL*Loader 更好的方法来处理此上传过程,或者我可以在控制文件或命令行中进行一些更改以阻止它死于可怕的死亡?
在进程开始时,我截断要加载到的表,然后使用以下控制文件运行此命令行:
命令行:
C:\Oracle\ora92\BIN\SQLLDR.EXE userid=ID/PASS@DB_ID load=10000000 rows=100000 DIRECT=TRUE SKIP_INDEX_MAINTENANCE=TRUE control=ControlFile.ctl data=logfile.log
控制文件:
UNRECOVERABLE
Load DATA
INFILE *
Append
PRESERVE BLANKS
INTO TABLE MY_REPORT_TABLE
FIELDS TERMINATED BY ","
(
filler_field1 FILLER char(16),
filler_field2 FILLER char(16),
time TIMESTAMP 'MMDDYYYY-HH24MISSFF3' ENCLOSED BY '"',
partne ENCLOSED BY '"',
trans ENCLOSED BY '"',
vendor ENCLOSED BY '"' "SUBSTR(:vendor, 1, 1)",
filler_field4 FILLER ENCLOSED BY '"',
cache_hit_count,
cache_get_count,
wiz_trans_count,
wiz_req_size,
wiz_res_size,
wiz_trans_time,
dc_trans_time,
hostname ENCLOSED BY '"',
trans_list CHAR(2048) ENCLOSED BY '"' "SUBSTR(:trans_list, 1, 256)",
timeouts,
success ENCLOSED BY '"'
)
一旦所有日志都完成加载,我会重建表上的索引,然后开始报告过程。似乎它现在只是在随机日志上死去,重新运行它每次都会在不同的点失败。
UNRECOVERABLE 和 SKIP_INDEX_MAINTENANCE 的原因是为了加快加载速度。事实上,加载每个日志仍然需要 7-12 分钟,如果没有这些日志,情况会更糟。总的来说,这个过程从开始到结束大约需要 18 个小时。