0

我有一个每周报告作业,我必须加载大约 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 个小时。

4

2 回答 2

0

100000 非常低,但请与您的 DBA 确认您对所有这些插入有足够的撤消。请他们在运行进程时对其进行监控

logfile.log 上还有什么内容吗?还要让您的 DBA 检查 alert.log

问候,

于 2011-07-08T03:59:52.013 回答
0

你是什​​么意思'死'?日志中有什么东西吗?

如果您必须让 DBA 终止会话,这意味着数据库会话仍然处于活动状态。如果是这样,它要么在加载、等待或在错误后回滚。从 DBA 那里找出它正在做的事情。如果它正在回滚,您应该让它完成,以便可以返回错误。

我会查看外部表而不是 SQL Loader。这些文件需要可在 DB 服务器上访问,但这使其成为更简单的 SQL 操作,这可能意味着更好的错误处理。

于 2011-07-08T01:04:51.700 回答