[原]使用可传输表空间修改Schema Name

我同学 Frank 尝试通过修改数据字典表来达到修改 Schema Name 的目的,但是引出了一大堆问题,详看这两博客:

Change Schema Name & ORA-01031: insufficient privileges (on SYS.DMBS_SESSION), ORA-28100, etc...

Change Schema Name (II)

以往我会通过 exp/imp 或者 expdp/impdp 完成类似的数据迁移,但是如果数量比较大,导出的可能性比较低,如果仅为修改一个Schema Name 而去导入导出2~3T的数据,那简直就是又一出“一个馒头引发的血案”。

考虑到以上问题,我尝试使用可传输表空间来完成这项任务。

 

创建测试环境

为 frank 建立用户和相应的表空间:

create tablespace frank
datafile 
  '/u02/oradata/ora10g/ORA10G/ora10g/frank01.dbf' size 20M autoextend on
logging
segment space management auto
extent management local;

create user frank
identified by frank
default tablespace frank;
grant connect to frank;
grant resource to frank;
revoke unlimited tablespace from frank;
alter user frank quota unlimited on frank;  

使用用户 frank 进行登录,然后创建一些对象,例如表 objects :

create table objects as select * from all_objects
insert into objects select * from objects ; 
insert into objects select * from objects ; 
insert into objects select * from objects ; 
insert into objects select * from objects ; 
commit;

现在 objects 这个表有“很多很多”数据,移动起来“非常非常”困难,但我又必须修改 frank 这个 Schema Name 为 killkill

 

导出成可传输表空间

我选用数据泵配合可传输表空间,所以需要创建一个 directory 出来:

create or replace directory DATAPUMP as '/home/ora10g/datapump';
grant read,write on directory DATAPUMP to public ; 

将表空间 frank 设为只读:

alter tablespace frank read only;

在命令行将表空间 frank “导出”,其实是导出数据字典,这个文件很小。

expdp system/oracle dumpfile=expdp_frank.dmp directory=datapump transport_tablespaces=frank

 

清理旧的Schema

将表空 frank offline :

alter tablespace frank offline ; 

然后将数据文件改名,以适应新的表空间命名规范,在命令行中执行:

cd /u02/oradata/ora10g/ORA10G/ora10g/
mv ./frank01.dbf ./killkill01.dbf

清理 Frank,我比较狠,关于Frank 的东西全部干掉:

drop user frank cascade;
drop tablespace frank including contents; 

 

从可传输表空间导入

首先,要为新的 Schema 建一个用户,就叫 killkill 吧:

create user killkill
identified by killkill;
grant connect to killkill;
grant resource to killkill;

我们稍后再为 killkill 指定默认表空间。

在命令行中导入:

impdp system/oracle DUMPFILE=expdp_frank.dmp DIRECTORY=DATAPUMP         \
  TRANSPORT_DATAFILES=/u02/oradata/ora10g/ORA10G/ora10g/killkill01.dbf  \
  REMAP_SCHEMA=(frank:killkill)  \
  REMAP_TABLESPACE=(frank:killkill) 

注意,REMAP_SCHEMA 就是修改 Schema Name 的关键,顺便将表空间的名字也改过来(REMAP_TABLESPACE)。

导入完毕,将新导入的表空间 killkill 设为 read write 模式,并设定为用户 killkill 的默认表空间:

alter tablespace killkill read write ;
alter user killkill default tablespace killkill ;

 

登录验收

这个就很简单了:

connect killkill/killkill
select count(*) from objects; 

 

小结

回顾整个过程,我们所需的磁盘空间实际上就是导出 expdp_frank.dmp 的文件大小,本次实验,该文件大小为 80K ,非常小;将数据文件改名,只要不是夸文件系统的移动,那几乎就是不需要时间和I/O的;导入可传输表空间,也就是导入那个80K的文件,即使普通的PC机也不是什么难事。

虽然整个过程比较繁琐,但是基本不会出错。

但是话说回来,如果用户 Frank 有几个Schema,所有 Schema 都放在一个表空间中,那么就不能用这个方法了。

posted @ 2010-08-10 22:05  killkill  阅读(1030)  评论(1编辑  收藏  举报