可传输表空间概述
Oracle 的可传输表空间特性通过将 元数据和数据文件 简单地从一个数据库移动到另一个数据库,提供 在数据库之间有效移动大数据的一种简易方法。代替重新创建对象,可移植表空间可以让 毫不费力地移动大对象,而所花费的时间是你手动创建这些对象的时间。 可移植表空间包括将属于源数据库的所有数据文件拷贝到目标数据库,并将关于表空间 数据目录信息从源数据库拷贝到目标数据库。因此,数据泵取导出和导入实用程序是可移 表空间特性的一部分。还可以传送属于表的索引表空间,使整个数据移植非常地快。
可移植表空间的应用场景 :
把数据从源数据库移动到数据仓库
把数据从升级数据库移动到数据集市
把数据从数据仓库移动到数据集市
执行表空间时间点恢复 (PITR)
归档历史数据
然而,在 Oracle9i 数据库和更低版本中,可传输表空间仅限于在目标数据库和源数据库都运行在同一操作系统平台上的少数情况下才有用 — 例如,您不能在 Solaris 和 HP-UX 平台之间传输表空间。
在Oracle 数据库 10g 中,这个局限消失了。
字节顺序和平台
数据文件所以不能跨平台,主要是由于不同平台的字节顺序不同,这是计算机领域由来已久的问题之一,在各种计算机体系结构中,由于对于字、字节等的存储机制有所不同,通信双方交流的信息单元(比特、字节、字、双字等)应该以什么样的顺序进行传送就成了一个问题,如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。
目前在各种体系的计算机中通常采用的字节存储机制主要有两种:Big-Endian和Little-Endian 。
一些操作系统(包括Windows)在低位内存地址中存放二进制数据的最低有效字节,因此这种系统被称为Little Endian;一些操作系统(包括Solaris)将最高有效字节存储在低位内存地址中,因此这种系统被称为Big Endian。
举一个简单点的例子,假如1122这样一个数据要存入不同系统,对于Little Endian的系统,存储的顺序就是2211,小头在前;而对于Big Endian的系统来说,存储顺序就是1122,大头在前,显然Big Endian更符合我们通常的语言习惯。
那么跨平台的问题就出现了,当一个Little Endian的系统试图从一个Big Endian的系统中读取数据时,就需要通过转换,否则不同的字节顺序将导致数据不能被正确读取。
数据库所处平台的字节序可通过如下查询得到
SQL>select * from v$transportable_platform
PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT
----------- -------------------------------------- --------------
1 Solaris[tm] OE (32-bit) Big
2 Solaris[tm] OE (64-bit) Big
7 Microsoft Windows IA (32-bit) Little
10 Linux IA (32-bit) Little
6 AIX-Based Systems (64-bit) Big
3 HP-UX (64-bit) Big
5 HP Tru64 UNIX Little
4 HP-UX IA (64-bit) Big
11 Linux IA (64-bit) Little
15 HP Open VMS Little
8 Microsoft Windows IA (64-bit) Little
PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT
----------- -------------------------------------- --------------
9 IBM zSeries Based Linux Big
13 Linux 64-bit for AMD Little
16 Apple Mac OS Big
12 Microsoft Windows 64-bit for AMD Little
17 Solaris Operating System (x86) Little
18 IBM Power Based Linux Big
传输表空间
传输表空间的简要操作步骤
1) 确定平台的 Endian 格式
2) 确保表空间为自包含并使其只读
3) 用 exp、expdp等实用程序导出元数据
4) 转换数据文件以匹配 Endian 格式 ( 若一致可跳过)
5) 拷贝文件到目标系统
6) 使用 imp导入实用程序导入元数据
1、确定平台的 Endian 格式
源平台
SQL> col PLATFORM_NAME for a30
SQL> SELECT d.platform_name, endian_format FROM v$transportable_platform tp, v$database d WHERE tp.platform_name = d.platform_name;
PLATFORM_NAME ENDIAN_FORMAT
------------------------------ --------------
Linux IA (32-bit) Little
目标平台:
SQL> col platform_name for a40
SQL> SELECT d.platform_name, endian_format FROM v$transportable_platform tp, v$database d WHERE tp.platform_name = d.platform_name;
PLATFORM_NAME ENDIAN_FORMAT
------------------------------ --------------
Linux IA (32-bit) Little
这里平台之间的字节序一致,不需要转换。
2、确保表空间为自包含并使其只读
自包含表示用于传输的内部表空间集没有任何对象引用指向外部表空间集。自包含分为两种:一般自包含表空间集和完全(严格)自包含表空间集。
下面是一些典型的违反自包含的例子:
索引在待传输表空间集中而表却不在,即索引在内部表空间集,而表在外部表空间集。(注意,如果表在待传输表空间集中,而索引不在并不违反自包含原则,即表在内部表空间集,而索引在外部表空间集,不违反自包含。当然如果你坚持这样传输的话,会造成目标库中该表索引丢失)。
分区表中只有部分分区在待传输表空间集(对于分区表,要么全部包含在待传输表空间集中,要么全不包含,解决:需要进行分区交换,完全包含在内部表空间集中)。
待传输表空间中,对于引用完整性约束,如果约束指向的表不在待传输表空间集,则违反自包含约束;但如果不传输该约束,则与约束指向无关。
对于包含LOB列的表,如果表在待传输表空间集中,而Lob列不在,也是违反自包含原则的。
自包含还有严格(strict)或完全(full)self_contained.这时:
set the TTS_FULL_CHECK parameter to TRUE,对象及其依赖对象完全在内部表空间集
而非严格自包含,表在内部表空间集,依赖于表的对象在外部白空间集不违反,但只是依赖于表的对象在内部表空间集,而表在外部表空间集就违反了。
我们可以通过使用dbms_tts包里的存储过程transport_set_check,检查要传输的表空间是否是自包含。具体定义如下
PROCEDURE TRANSPORT_SET_CHECK
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
TS_LIST CLOB IN
INCL_CONSTRAINTS BOOLEAN IN DEFAULT
FULL_CHECK BOOLEAN IN DEFAULT
TS_LIST表示要传输的表空间名称列表,不同的表空间名称之间以逗号隔开
INCL_CONSTRAINTS表示要检查的子表外建(true表示是,false表示否。默认为false),也就是说,如果在要传输的表空间里的某个子表上存在外建,且该外建所指向的父表在其他表空间内,则INCL_CONSTRAINTS为true,表明违反了自包含。否则为false,表明没有违反自包含。
FULL_CHECK表示是否要检查表的索引(true表示是,false表示否。默认为false),也就是说,如果在要传输的表空间里的某个表的索引位于其他表空间内,FULL_CHECK则为true,表明违反了自包含。否则为false,表明没有违反自包含。检查后的结果在transport_set_violations视图中体现。
下面做一个简单测试
外建约束测试
SQL> create table t tablespace users
2 as
3 select object_id,object_name from user_objects;
Table created.
SQL> create table t_child tablespace example
2 as
3 select object_id,object_name from user_objects
4 where 1=2;
Table created.
SQL> alter table t add primary key(object_id);
Table altered.
SQL> alter table t_child add foreign key(object_id)
2 references
3* t(object_id)
进行外键检查
SQL> execute dbms_tts.transport_set_check('example',incl_constraints=>true);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
VIOLATIONS
--------------------------------------------------------------------------------
Constraint SYS_C005435 between table HR.T in tablespace USERS and table HR.T_CHI
LD in tablespace EXAMPLE
SQL> execute dbms_tts.transport_set_check('users',incl_constraints=>true);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
no rows selected
将users和example表空间一起进行检查
SQL> execute dbms_tts.transport_set_check('users,example',incl_constraints=>true);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
no rows selected
进行FULL_CHECK测试
SQL> create index t_index on t_child(object_id) tablespace indx;
Index created.
SQL> execute dbms_tts.transport_set_check('example',full_check=>true);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
VIOLATIONS
--------------------------------------------------------------------------------
Index HR.T_INDEX in tablespace INDX points to table HR.T_CHILD in tablespace EXA
MPLE
SQL> execute dbms_tts.transport_set_check('example,indx',full_check=>true);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
no rows selected
将索引和外键同时检查。
SQL> execute dbms_tts.transport_set_check('users,example,indx',true,true);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
no rows selected
现在将users,example,indx表空间置为只读
SQL> alter tablespace users read only;
Tablespace altered.
SQL> alter tablespace example read only;
Tablespace altered.
SQL> alter tablespace indx read only;
Tablespace altered.
3、用 exp、expdp等实用程序导出元数据
$ exp \'/ as sysdba \' file=usr_exp_idx.tbs.dmp transport_tablespace=y tablespace=users,example,indx
LRM-00101: unknown parameter name 'tablespace'
EXP-00019: failed to process parameters, type 'EXP HELP=Y' for help
EXP-00000: Export terminated unsuccessfully
[oracle@dg1 ~]$ exp \'/ as sysdba \' file=usr_exp_idx.tbs.dmp transport_tablespace=y tablespaces=users,example,indx
Export: Release 10.2.0.1.0 - Production on Thu Nov 17 10:43:09 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses WE8ISO8859P1 character set (possible charset conversion)
Note: table data (rows) will not be exported
About to export transportable tablespace metadata...
...........................................................................................................
. end transportable tablespace metadata export
Export terminated successfully without warnings.
4、转换数据文件以匹配 Endian 格式 ( 若一致可跳过)
这里笔者的平台字节序是一致的不需要转换,如需转换则可以使用如下命令
$ rman target /
RMAN> convert tablespace trans
2> to platform 'Microsoft Windows IA (32-bit)'
3> format '/tmp/%N_%f';
5、拷贝文件到目标系统
$ scp /u01/app/oracle/oradata/czmmiao/indx01.dbf /u01/app/oracle/oradata/czmmiao/example.dbf /u01/app/oracle/oradata/czmmiao/users01.dbf usr_exp_idx.tbs.dmp 192.168.0.102:/home/oracle/
oracle@192.168.0.102's password:
indx01.dbf 100% 10MB 5.0MB/s 00:02
example.dbf 100% 100MB 4.4MB/s 00:23
users01.dbf 100% 5128KB 5.0MB/s 00:01
usr_exp_idx.tbs.dmp 100% 1072KB 1.1MB/s 00:01
6、使用 imp导入实用程序导入元数据
在导入之前我们需要确认目标数据库具有我们想导入的表空间内的对象的属主。
源数据库的对象属主
SQL> select distinct owner from dba_segments where tablespace_name in ('EXAMPLE','USERS','INDX');
OWNER
------------------------------
HR
SCOTT
OE
PM
SH
IX
SYS
TRANS
如果在目标平台没有存在该用户就会报如下错误。
IMP-00003: ORACLE error 29342 encountered
ORA-29342: user HR does not exist in the database
ORA-06512: at "SYS.DBMS_PLUGTS", line 1895
ORA-06512: at line 1
IMP-00000: Import terminated unsuccessfully
注意,如果在目标平台已经存在相应的表空间也无法成功导入,报错如下
IMP-00003: ORACLE error 29349 encountered
ORA-29349: tablespace 'USERS' already exists
ORA-06512: at "SYS.DBMS_PLUGTS", line 1801
ORA-06512: at line 1
IMP-00000: Import terminated unsuccessfully
执行导入命令
$ imp \'/ as sysdba \' file=usr_exp_idx.tbs.dmp transport_tablespace=y tablespaces=example,users,indxdatafiles=/home/oracle/users01.dbf,/home/oracle/example.dbf,/home/oracle/indx01.dbf
注意表空间名要与源数据库一致
将这3个表空间设为可读写
SQL> alter tablespace example read write;
Tablespace altered.
SQL> alter tablespace indx read write;
Tablespace altered.
SQL> alter tablespace users read write;
Tablespace altered.
至此,导入成功。
来自:http://blog.csdn.net/yrg5101/article/details/7775123