在 Oracle 中通过 DB Link 使用 BLOBS 拆分大量 table
Splitting a massive table with BLOBS over DB Link in Oracle
我有一个有趣的问题。我正在将数据从一个数据库迁移到另一个数据库,其中包括数以百万计的 BLOB,其元数据总计 TB 级数据。
由于多种原因,这必须通过 DB Link 完成,并且另一侧包含 BLOB 的视图未编入索引。这是因为没有一个唯一的键,并且逻辑复杂
唯一标识文档(这只是我们迁移到新系统的一个原因)。我想做的是:
1) 将行拆分成单独的块进行传输,这样我就可以并行访问,也不会在发生崩溃时丢失所有内容
2) 插入暂存 tables
3) 一旦一切都结束了,我将把暂存 tables 合并到生产 tables 并转储临时
s
由于 Oracle 对通过 DB 的 LOB 引用的限制,我无法在视图上打开游标 link。
我使用 insert into 绕过 Oracle 限制,但我确实需要对行进行切片。我已多次尝试 运行 我的脚本,但我的会话会在 2 天后被终止,我失去了一切。
我尝试通过 rownum 对它进行分块以使用像分块这样的分页,但它没有用。这是我的代码(来自 http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html 的帮助):
-- for second chunk
procedure process_chnk_2 (
l_slice pls_integer;
)
begin
execute immediate 'insert /*+ append */ into DESTINATION_TABLE
select *
from
( select q.*
,rownum rnum
from
( select *
from migr_view.MIGR_BLOB@DB_LINK) q
where rownum <= l_slice * 2
) where rnum >= l_slice
';
commit;
end process_chnk_2;
这不起作用,因为您仍然需要使用 BLOB 进行查询。
我曾想过选择其中一个文本列,然后像这样加入原始视图:
-- for second chunk
procedure process_chnk_2 (
l_slice pls_integer;
)
begin
execute immediate 'insert /*+ append */ into DESTINATION_TABLE
select *
from
( select q.text_that_is_not_quite_a_key
,q.second_that_is_not_quite_a_key
,q.third_that_is_not_quite_a_key
,q.fourth_that_is_not_quite_a_key
.
.
.
,rownum rnum
from
( select *
from migr_view.MIGR_BLOB@DB_LINK) q
where rownum <= l_slice * 2
) z
, migr_view.MIGR_BLOB@DB_LINK x
where z.rnum >= l_slice
and z.text_that_is_not_quite_a_key = x.text_that_is_not_quite_a_key
and z.second_that_is_not_quite_a_key = x.second_that_is_not_quite_a_key
and z.third_that_is_not_quite_a_key = x.third_that_is_not_quite_a_key
and z.fourth_that_is_not_quite_a_key = x.fourth_that_is_not_quite_a_key
.
.
.
';
commit;
end process_chnk_2;
但是,我们正在谈论加入一个 table 具有数百万行并且没有索引只是为了获取切片......你知道这需要多长时间吗?
我不会使用工具,甚至数据泵...只能使用脚本...
感谢您的帮助!
我在过去两天尝试将这个想法放在一起 - 我只是提出它作为答案,但我想听听你的建议,因为这很丑!!虽然我们无法以任何排序顺序识别唯一键,但通过混合键和提取数字,我们实际上可以找到一个值范围来切片,并且它分布相当均匀。
l_stmt := q'{insert /*+ NOLOGGING NOWAIT */
into DESTINATION_TABLE
select *
from migr_view.migr_blob@DB_LINK
where to_number(regexp_substr(not_key_1 || not_key_2 || not_key_3...,
'[[:digit:]]+')) >= }' || i_start_slice || q'{
and to_number(regexp_substr(not_key_1 || not_key_2 || not_key_3...,
'[[:digit:]]+')) < }' || l_end_slice;
我有一个有趣的问题。我正在将数据从一个数据库迁移到另一个数据库,其中包括数以百万计的 BLOB,其元数据总计 TB 级数据。 由于多种原因,这必须通过 DB Link 完成,并且另一侧包含 BLOB 的视图未编入索引。这是因为没有一个唯一的键,并且逻辑复杂 唯一标识文档(这只是我们迁移到新系统的一个原因)。我想做的是:
1) 将行拆分成单独的块进行传输,这样我就可以并行访问,也不会在发生崩溃时丢失所有内容 2) 插入暂存 tables 3) 一旦一切都结束了,我将把暂存 tables 合并到生产 tables 并转储临时
s由于 Oracle 对通过 DB 的 LOB 引用的限制,我无法在视图上打开游标 link。 我使用 insert into 绕过 Oracle 限制,但我确实需要对行进行切片。我已多次尝试 运行 我的脚本,但我的会话会在 2 天后被终止,我失去了一切。
我尝试通过 rownum 对它进行分块以使用像分块这样的分页,但它没有用。这是我的代码(来自 http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html 的帮助):
-- for second chunk
procedure process_chnk_2 (
l_slice pls_integer;
)
begin
execute immediate 'insert /*+ append */ into DESTINATION_TABLE
select *
from
( select q.*
,rownum rnum
from
( select *
from migr_view.MIGR_BLOB@DB_LINK) q
where rownum <= l_slice * 2
) where rnum >= l_slice
';
commit;
end process_chnk_2;
这不起作用,因为您仍然需要使用 BLOB 进行查询。
我曾想过选择其中一个文本列,然后像这样加入原始视图:
-- for second chunk
procedure process_chnk_2 (
l_slice pls_integer;
)
begin
execute immediate 'insert /*+ append */ into DESTINATION_TABLE
select *
from
( select q.text_that_is_not_quite_a_key
,q.second_that_is_not_quite_a_key
,q.third_that_is_not_quite_a_key
,q.fourth_that_is_not_quite_a_key
.
.
.
,rownum rnum
from
( select *
from migr_view.MIGR_BLOB@DB_LINK) q
where rownum <= l_slice * 2
) z
, migr_view.MIGR_BLOB@DB_LINK x
where z.rnum >= l_slice
and z.text_that_is_not_quite_a_key = x.text_that_is_not_quite_a_key
and z.second_that_is_not_quite_a_key = x.second_that_is_not_quite_a_key
and z.third_that_is_not_quite_a_key = x.third_that_is_not_quite_a_key
and z.fourth_that_is_not_quite_a_key = x.fourth_that_is_not_quite_a_key
.
.
.
';
commit;
end process_chnk_2;
但是,我们正在谈论加入一个 table 具有数百万行并且没有索引只是为了获取切片......你知道这需要多长时间吗?
我不会使用工具,甚至数据泵...只能使用脚本... 感谢您的帮助!
我在过去两天尝试将这个想法放在一起 - 我只是提出它作为答案,但我想听听你的建议,因为这很丑!!虽然我们无法以任何排序顺序识别唯一键,但通过混合键和提取数字,我们实际上可以找到一个值范围来切片,并且它分布相当均匀。
l_stmt := q'{insert /*+ NOLOGGING NOWAIT */
into DESTINATION_TABLE
select *
from migr_view.migr_blob@DB_LINK
where to_number(regexp_substr(not_key_1 || not_key_2 || not_key_3...,
'[[:digit:]]+')) >= }' || i_start_slice || q'{
and to_number(regexp_substr(not_key_1 || not_key_2 || not_key_3...,
'[[:digit:]]+')) < }' || l_end_slice;