一、基本环境

源库:

DB_NAME:racdb(rac)     HOSTNAME:note1note2    PUBLIC IP:172.16.1.7172.16.1.8   STORAGE:ASM  

OS_VERSION:RedHat6.5     ORACLE_VERSION:11.2.0.4.0

目标库:

DB_NAME:testdb(single instance)     HOSTNAME:iscsi-asm   IP:172.16.1.20         STORAGE:file system   OS_VERSION:RedHat6.5     ORACLE_VERSION:11.2.0.4.0

迁移表空间:MYTEST

 

二、DATAPUMP迁移表空间

1、源数据库创建测试表空间

SQL> create tablespace mytest datafile'+data' size 100m;    
 
Tablespace created.
 
SQL> create user mytest identified bymytest123 default tablespace mytest;
 
User created.
 
SQL> grant connect,resource to mytest;
 
Grant succeeded.
 
SQL> create table mytest.t1 as select *from dba_segments;
 
Table created.
 
SQL> select count(1) from mytest.t1;
 
COUNT(1)
----------
 4795

2、确认源数据库的表空间是否自包含

SQL> exec dbms_tts.transport_set_check('mytest',true,true);
 
PL/SQL procedure successfully completed.
 
SQL> select * from transport_set_violations;
 
no rows selected

查看检查的结果,无输出说明该表空间是自包含的,也就是说该表空间的对象没有依赖其它表空间。接下来,我在测试表mytest.t1上建个索引,存储在users表空间上,再看看查询transport_set_violations的结果。

SQL> alter user mytest quota unlimited on users;
 
User altered.
 
SQL> create index mytest.t1_owner_idx on mytest.t1(owner) tablespace users;
 
Index created.
 
SQL> exec dbms_tts.transport_set_check('mytest',true,true);
 
PL/SQL procedure successfully completed.
 
SQL> select * from transport_set_violations;
 
VIOLATIONS
--------------------------------------------------------------------------------
ORA-39907: Index MYTEST.T1_OWNER_IDX in tablespace USERS points to table MYTEST.
T1 in tablespace MYTEST.

从查询transport_set_violations的结果中可以看出,该表空间的对象T1_OWNER_IDX这个索引依赖其它表空间USERS,所以它不是自包含的,利用datapumprman的方式都是不支持,因此,可使用alter table/index move的方式不在自包含的表空间的对象移动到同一表空间之后再迁移表空间。这里我将索引T1_OWNER_IDX先删除。

3、确认平台是否兼容

SQL> select t.* fromv$transportable_platform t,v$database d where t.platform_name =d.platform_name;
 
PLATFORM_ID  PLATFORM_NAME                          ENDIAN_FORMAT
-------------------------------------------------- --------------
         13  Linuxx86 64-bit                        Little

目前源库和目标库都是RedHat 6.5,相同的OS,不存在跨平台的情况,所以这里简单的说一下就行,可通过查询v$transportable_platform视图的endian_format进行对比,若相同则说明可以进行跨平台的迁移。

补充:源端数据库版本和目标端数据库版本的问题,根据datapump的特性高进低出,所以高版本到低版本应该是不支持的,而低到高是没问题的。

4、将表空间置为read only状态

SQL> alter tablespace mytest read only;
 
Tablespace altered.

5、导出表空间metadata

SQL> create directory zwdir as'/u/app/oracle/zwdir';
 
Directory created.
 
[oracle@note1 zwdir]$ expdp \'\/ assysdba\'  directory=zwdirdumpfile=mytest.dmp nologfile=y transport_tablespaces=mytest

wKiom1ihxjbxqU6eAAGAnl69ho0721.jpg-wh_50

6、将表空间置为read write状态

SQL> alter tablespace mytest read write;
 
Tablespace altered.

7cp源库数据文件和dmp到目标库

这里需要注意的是源库数据文件是存储在ASM中的,需要从ASM中先拷贝到本地文件系统上,在此过程中需要将数据文件的所属用户由grid修改为oracle。拷贝过程这里就不做记录了。

8、目标端执行导入

SQL> create user mytest identified bymytest123;
 
User created.
 
SQL> grant connect,resource to mytest;
 
Grant succeeded.

先需要建立一个相同的用户,不然会报如下的错误:

ORA-39123: Data Pump transportabletablespace job aborted

ORA-29342: user MYTEST does not exist inthe database

在导入之前,需要考虑源库与目标库的字符集是否相同,如果不同,则需要修改为相同的字符集;还需要考虑两个数据库之间的BLOCK_SIZE是否一致,若不一致,需要修改DB_nK_CACHE_SIZE的大小。

[oracle@iscsi-asm ~]$ impdp \'\/ assysdba\'  directory=zwdirdumpfile=mytest.dmp nologfile=ytransport_datafiles='/u/app/oracle/oradata/datafile/MYTEST.279.935793141'

wKiom1ihxyiCLA7zAADtZT0qdnU758.jpg-wh_50

这里是从ASM到文件系统,读者可以思考下:从文件系统到ASM的迁移、ASMASM之间的迁移,其实都是差不多的。

9、进行验证

SQL> select count(1) from mytest.t1;
 
 COUNT(1)
----------
     4795
      
SQL> alter tablespace mytest read write;
 
Tablespace altered.

10Datapump迁移表空间的总结:

transport_tablespace是需要满足许多条件的,从上可以知道,需要字符集相同,表空间是自包含的,如果跨平台的话,还需确认endian_format是否一致。最关键的是需要迁移的表空间需要在READ ONLY状态,能读不能写,这对于7*24环境的系统而言,是没有办法接受的,那么是否有办法解决该问题呢?有的,那就是RMAN TRANSPORT TABLESPACE


三、RMAN迁移表空间

1、RMAN备份数据库

源库需要备份整库和所有的归档日志,因为除了目标表空间的备份以外,RMAN还需要SYSTEMSYSAUX以及UNDO表空间的备份,如果任意一个表空间的备份不存在,则就会导致RMAN-06019: 无法转换表空间名称的错误。

RMAN> backup database  plus archivelog format '/u/app/oracle/zwdir/full_bak_%T_%t.bak';
 
RMAN> transport tablespace mytesttablespace destination '/u/app/oracle/zwdir' auxiliary destination'/u/app/oracle/zwdir/mytest';

此时需要迁移的表空间数据文件,dmp文件,导入脚本等都在/u/app/oracle/zwdir目录下,而/u/app/oracle/zwdir/mytest建立的辅助实例的临时文件都会被删除。观察一下生成的导入脚本文件:

wKioL1ihx8rSxpzpAABSn1LIYI8177.jpg-wh_50

这里可以发现从ASM存储到文件系统上数据文件使用了OMF的方式进行管理。

2、CP生成的文件到目标库

[oracle@note1 zwdir]$ scp -ro1_mf_mytest_db3jhv2w_.dbf dmpfile.dmp impscrpt.sql  172.16.1.20:/u/app/oracle/zwdir/
oracle@172.16.1.20's password: 
o1_mf_mytest_db3jhv2w_.dbf                    100%  100MB 100.0MB/s   00:01   
dmpfile.dmp                                   100%  112KB 112.0KB/s   00:00   
impscrpt.sql                                   100%2094     2.0KB/s   00:00

3、导入目标库

SQL> @impscrpt.sql
 
Directory created.
 
Directory created.
 
PL/SQL procedure successfully completed.
 
Directory dropped.
 
Directory dropped.

4、进行验证

SQL> select tablespace_name,status fromdba_tablespaces where tablespace_name='MYTEST';
 
TABLESPACE_NAME               STATUS
------------------------------------------------
MYTEST                             READ ONLY
 
SQL> select count(1) from mytest.t1;
 
 COUNT(1)
----------
     4795

5、RMAN迁移表空间的总结:

对比datapump迁移表空间,rman迁移表空间更加简单实用,可以说是rmandatapump迁移的方式进行脚本的集成。虽然,以上我的操作步骤很简单,datapump该考虑的条件,使用rman也是一样需要考虑的,字符集相同,表空间是自包含的,如果跨平台的话,还需确认endian_format一致,两个数据库之间的BLOCK_SIZE也要一致等。

 

参考官网相关文章:

TransportingTablespaces Between Databases

http://docs.oracle.com/cd/E11882_01/server.112/e25494/tspaces013.htm

CreatingTransportable Tablespace Sets

http://docs.oracle.com/cd/E11882_01/backup.112/e10642/rcmttbsb.htm