在 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;