ITPub博客

首页 > 数据库 > Oracle > 表空间迁移办法补充

表空间迁移办法补充

原创 Oracle 作者:regonly1 时间:2014-02-08 14:51:12 0 删除 编辑


 


上次总结了表空间迁移办法(http://blog.itpub.net/12932950/viewspace-741543),发现还存在几个不足的地方:
1、没有考虑iot的情况。对于iot,是不能rebuild其主键索引的,要move表才行;
2、没有考虑存在long字段的表。这类表不能直接做move,直接处理就报错了;

同时,也有人提到了用exp/imp的可传输表空间方法来实现迁移。
但我觉得既然要exp/imp了,那就干脆进一步,用expdp/impdp的remap_tablespace了,exp/imp反而不方便,还要建临时表空间什么的,多费力。
具体可参考我的另一个blog《数据泵实现数据迁移到异地库》(http://blog.itpub.net/12932950/viewspace-752301/)。

言归正传,这次对前面提到的这两个问题做了补充:
1、检查是否为iot,如果是,则排除对iot的主键索引的rebuild,改为对表的move;
2、增加条件不能存在long类型的字段,存在则单独处理;


修改后的sql如下:
with tmp as(
select a.owner, a.TABLE_NAME, c.segment_name, c.segment_type, c.tablespace_name
   from dba_tables a, dba_constraints b, dba_segments c
  where b.constraint_name = c.segment_name
    and b.owner = c.owner
    and b.constraint_type = 'P'
    and a.TABLE_NAME = b.table_name
    and a.OWNER = b.owner
    and a.iot_type = 'IOT')
select segment_type, segment_name, partition_name,
        case segment_type
        when 'TABLE' then 'alter table ' || owner || '.' || segment_name || ' move tablespace dbs_temp;'
        when 'INDEX' then 'alter index ' || owner || '.' || segment_name || ' rebuild tablespace dbs_temp;'
        when 'INDEX PARTITION' then 'alter index ' || owner || '.' || segment_name || ' rebuild tablespace dbs_temp;'
        when 'TABLE PARTITION' then 'alter table ' || owner || '.' || segment_name || ' move partition ' || partition_name || ' tablespace dbs_temp;'
        end sqltext
   from dba_segments b
  where not exists(select 1 from tmp a where a.segment_name = b.segment_name and a.owner = b.owner)
    and tablespace_name = 'MOVE_TBS'
    and segment_type not like 'LOB%'
    and segment_name not like 'BIN%'
    and not exists(select 1 from dba_tab_columns a
                    where (a.data_type like 'LONG%' or a.data_type like '%LOB%')
                      and a.table_name = b.segment_name
                      and a.owner = b.owner
                      and b.segment_type like 'TABLE%')
  union all
select segment_type, segment_name, null, 'alter table ' || table_name || ' move tablespace dbs_temp;'
   from tmp
  where tablespace_name = 'MOVE_TBS'

对于存在long型字段的表,首先筛选出来:
select *
   from dba_segments b
  where tablespace_name = 'FUND_TABLE'
    and segment_name not like 'BIN%'
    and exists(select 1 from dba_tab_columns a
                where a.data_type like 'LONG%'
                  and a.table_name = b.segment_name
                  and a.owner = b.owner
                  and b.segment_type like 'TABLE%')

然后,用exp/imp导出再导入即可,当然,也有提到的用sqlplus copy也是一个不错的办法,还能减去中间dmp文件的过程,直接以数据流的形式实现。
不过,基于一个很简单的原因,sqlplus copy必须变更表名或变更用户名。

对于lob字段的处理可见前一篇帖子的内容,在这里不做赘述。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12932950/viewspace-1078090/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 空间迁移
请登录后发表评论 登录
全部评论

注册时间:2008-05-10

  • 博文量
    257
  • 访问量
    1037779