【IT168技术文档】
一、关于可传输表空间(Transportable Tablespaces)
可传输表空间的特性主要用于进行库对库的表空间复制,要进行传输的表空间必须置于read-only模式。如果生产库不允许表空间置为只读模式,没关系,方法还是有的,通过RMAN备份也可以创建可传输表空间集。要使用可传输表空间的特性,oracle至少是8i企业版或更高版本。如果是相同操作系统平台相互导入,则8i及以上版本均可支持,但如果是不同操作系统平台,数据库版本至少10g。被传输的表空间即可以是字典管理,也可以是本地管理。并且自oracle9i开始,被传输表空间的block size可以与目标数据库的block size不同。
可传输表空间(还有个集)最大的优势是其速度比export/import或unload/load要快的多。因为可传输表空间主要是复制数据文件到目标路径,然后再使用export/import或Data Pump export/import等应用仅导出/导入表空间对象的元数据到新数据库。
提示:本节中将完全采用Data Pump(数据泵)做为导入导出的工具。(什么是Data Pump,说来话短,Data Pump。。。。。其命令形式是impdp/expdp分别对应导入/导出功能,是自oracle10g开始提供的一种新的应用。功能和命令形式都与imp/exp极其类似,但其相互之间的导出文件并不兼容)不过,Data Pump和常规的imp/exp同样都能够被transportable tablespaces特性支持。但是如果被传输的表空间包含XMLTypes,就必须使用imp/exp。
通常有两种方式传输表空间:
手工操作。按本节中的步骤操作,含SQL*Plus, RMAN, IMP/EXP或Data Pump等各种指令操作。
使用OEM中的传送表空间向导。
要运行传送表空间向导:
1、使用具有EXP_FULL_DATABASE角色的用户登陆到OEM中;
2、点击维护(Maintenance)链接;
3、点击标题下方的"Transport Tablespaces"。
二、关于跨平台传输表空间
从oracle10g开始,你终于可以实现跨平台传输表空间了。无数的dba欢呼着,雀跃着。。。。
尽管仍非全部,但已经有很多平台可以支持跨平台的传送。可以通过查询V$TRANSPORTABLE_PLATFORM视图来确认哪些平台可以支持,该视图同时也可以获取各平台的ENDIAN_FORMAT(字节顺序byte ordering)
SQL> SELECT * FROM V$TRANSPORTABLE_PLATFORM ORDER BY PLATFORM_ID; PLATFORM_ID PLATFORM_NAME ENDIAN_FORMAT ----------- ---------------------------------------- -------------- 1 Solaris[tm] OE (32-bit) Big 2 Solaris[tm] OE (64-bit) Big 3 HP-UX (64-bit) Big 4 HP-UX IA (64-bit) Big 5 HP Tru64 UNIX Little 6 AIX-Based Systems (64-bit) Big 7 Microsoft Windows IA (32-bit) Little 8 Microsoft Windows IA (64-bit) Little 9 IBM zSeries Based Linux Big 10 Linux IA (32-bit) Little 11 Linux IA (64-bit) Little 12 Microsoft Windows 64-bit for AMD Little 13 Linux 64-bit for AMD Little 15 HP Open VMS Little 16 Apple Mac OS Big 17 Solaris Operating System (x86) Little 18 IBM Power Based Linux Big
已选择17行。
提示:关于字节顺序(byte ordering)
一些操作系统(包括 Windows)在低位内存地址中用最低有效字节存储多字节二进制数据;因此这种系统被称为低地址低字节序。相反,其它的操作系统(包括 Solaris)将最高有效字节存储在低位内存地址中,因此这种系统被称为低地址高字节序。当一个低地址高字节序的系统试图从一个低地址低字节序的系统中读取数据时,需要一个转换过程— 否则,字节顺序将导致不能正确解释读取的数据。不过,当在相同字节顺序的平台之间传输表空间时,不需要任何转换。
如果平台间的endian不同,那么在执行导入操作之之前必须首先转换源平台的表空间到目标格式,如果平台间endian format相同,则可以跳过转换的步骤,即使是不同平台。当然前提是各平台的数据库版本都不低于10g。
在表空间可被传输到不同平台之前,数据文件的文件头必须能够识别其所属的原平台是什么,对于oracle数据库初始化参数中COMPATIBLE置为10.0.0或更高之后,你必须至少将表空间置为read-write一次,这点非常重要,你现在还不知道我在说什么?没关系,很快就会知道的。
1、当你计划进行传输表空间之前,你有必要了解下列的一些信息:
源库和目标库的字符集和国家字符集必须相同。
要传输的表空间不能与目标服务器现有表空间名称重复。
有关联关系的对象(比如物化视图)或包含对象(比如表分区)一般情况下不能被传送,除非所有的关联对象都在表空间集(tablespace set)中。
自oracle10gR2开始,可以传输含XMLTypes的表空间,不过必须使用imp/exp而不能选择数据泵(impdp/expdp)。并确保imp/exp命令的CONSTRAINTS和TRIGGERS参数设置为Y。
下列脚本可以列出数据库中哪些表空间含XMLTypes:
select distinct p.tablespace_name from dba_tablespaces p, dba_xml_tables x, dba_users u, all_all_tables t where t.table_name = x.table_name and t.tablespace_name = p.tablespace_name and x.owner = u.username
2、传输表空间的特性并非功能较多的,还有些其它方面的限制:
高级队列(Advanced Queues):可传输表空间的特性并不支持8.0兼容的高级队列
系统表空间(SYSTEM Tablespace Objects):不能传输SYSTEM表空间或者SYS用户拥有的对象。
映射类型(Opaque Types):由应用指定并且映射到数据库(如RAW,BFILE等)的类型可以被传输,但是它们并不会被做为跨平台转换的一部分。其实际类型是什么只有指定它的应用清楚,所以必须保证这个应用解决读取各种endian问题后再考虑将其传输到新平台。
浮点数据(Floating-Point Numbers):BINARY_FLOAT和BINARY_DOUBLE类型可以使用数据泵导入导出但不支持EXP。
3、兼容性
从oracle10g开始,不论目标库运行在相同或不同的平台,表空间都可以传输到相同或更高版本的oracle库。但是如果生成传输表空间集oracle版本比目标库oracle版本高的话,数据库就会提示错误。
下表列出了源表空间和目标表空间之间在不同传输情况下oracle最低兼容版本。
|
传输条件
|
源表空间数据库
|
目标表空间数据库
|
|
数据库在相同平台
|
8i
|
8i
|
|
源库与目标库的block size不同
|
9i
|
9i
|
|
数据库在不同平台
|
10g
|
10g
|
下列步骤列出了传输一个表空间的大致过程。
1、检查平台
对于跨平台的传输,查询V$TRANSPORTABLE_PLATFORM视图检查两平台的endian format。如果相同平台的传输可以跳过此步。
2、选择自包含表空间集(self-contained set of tablespaces)
提示:啥叫自包含呢,自包含表示用于传输的内部表空间集没有任何对象引用指向外部表空间集。自包含分为两种:一般自包含表空间集和完全(严格)自包含表空间集。
下面是一些典型的违反自包含的例子:
索引在待传输表空间集中而表却不在。(注意,如果表在待传输表空间集中,而索引不在并不违反自包含原则,当然如果你坚持这样传输的话,会造成目标库中该表索引丢失)。
分区表中只有部分分区在待传输表空间集(对于分区表,要么全部包含在待传输表空间集中,要么全不包含)。
待传输表空间中,对于引用完整性约束,如果约束指向的表不在待传输表空间集,则违反自包含约束;但如果不传输该约束,则与约束指向无关。
对于包含LOB列的表,如果表在待传输表空间集中,而Lob列不在,也是违反自包含原则的。
看看,条件和限制还是很多,虽然我们的大脑里的脑细胞也黑多,但是如果你要传输大量数据,还想依靠脑细胞一个个做判断显然是不明智的,幸运的是额们地神oracle想到了这一点,于是它给了我们一张小纸条,上面写着几百个大字:检查是否自包含,请用DBMS_TTS.TRANSPORT_SET_CHECK,疗效好。该产品采用纯中药制成,无毒无副作用,口服针剂均可,ooo错了,是分严格方式和非严格方式验证。那么对于严格方式和非严格方式又有什么区别呢,这个问题如果又要用语言描述恐怕不仅占用大量字节而且又会将你的脑袋搅的一团乱,所以我们留待实践操作的时候通过实例来说明吧。
3、生成可传输表空间,还有个集(transportable tablespace set)
首先将要导出的表空间状态置为READ-ONLY。
可传输表空间集包含表空间集对应的数据文件以及含表空间结构信息即元数据的export文件(可以通过EXPDP或EXP执行导出)。
再次提示,如果导出的表空间中含XMLTypes,则必须使用EXP导入。
如果你准备传输表空间集到不同endian平台,必须首先转换表空间集的endian与目标平台相同。转换操作即可以在源库生成传输表空间集时进行,也可以在目标服务器导入传输表空间之前进行。注意,何时转换并非完全随意,它跟你的策略是有很大关系的,后面会有黑详细的介绍,瞪大眼睛表错过。
可传输表空间集创建完之后,可以将源库的表空间状态置为read-write。
4、传输表空间集
复制数据文件以及export文件到目标数据库。
如果需要转换,应该何时执行转换操作呢?
前面提到,如果涉及了endian的转换,可以在生成可传输表空间集时进行(源平台进行),或者在导入表空间集之前进行(目标平台进行),转换的命令都是一个,只是参数略有不同,关于命令的用法暂且不提,后面会有专门章节介绍和实践。在这里我们先来深入一个这个操作究竟放在哪里合适。按说这个操作放在哪里执行都可以,应该没有什么可争辩的,但是值的注意的是针对我们操作的数据库,特别是对于正在运行的生产数据库,三思建议你采用在目标平台上进行转换的操作,缘由如下:
1). 缩短停机时间
在创建可传输表空间集之前,需要将要传输的表空间状态置为read-only。你可以将数据文件迅速复制一份镜像,并生成包含元数据的export文件,然后即可将表空间状态置为read-write状态。这种安排使得表空间必须保持为只读的时间尽可能的短。
2). 提高执行性能
生产数据库往往同时在处理多个应用,而此时如果再用其进行转换操作可能增加系统负载,并且系统此时由于执行的任务较多,转换效率也并非最高。将转换操作移到目标平台进行,通常对于目标平台都是做为备份角色,其系统负载相对是比较低的,执行转换操作的效率相对也会更高。
3). 简化复制操作
通过在目标平台执行转换命令时指定db_file_name_convert参数,直接将数据文件转换到目标目录内,简化复制时的操作。
5、导入表空间集
使用IMPDP或IMP导入表空间集元数据到目标库,如果你采用的是Data Pump Import/Export,还可以将步骤更简练,Data Pump支持一个名为NETWORK_LINK的参数,通过该参数指定的数据链,你甚至可以跳过Expdp生成源库元数据的操作,Impdp通过数据库链接从源数据库中获得所需的元数据,并在目标数据库中重新创建它们。
导入完成之后,如果需要,将目标库中导入的表空间状态置为read-write。
这样我们整个跨平台的传输就完成了,整体来看步骤非常简单,就是"导出->复制->导入",简称传输三板斧。困难处并不是这把斧子重,而是不同情况下,你得能够明智的选择斧势,是劈是砍还是砸呢,不同的选择会有不同的结果,有时候你选择了开头,却选择不了这结果,一旦结果不是你想要的,没关系,oracle会再给你新的选择,下面我们就来看看这结果吧
终于要进入实践了,我们假设现有数据库a:SID=jssweb做为源数据库,数据库b:SID=jsstts做为目标数据库。从数据库a复制表空间jssweb到数据库b。下面是具体操作步骤:
一、确认平台是否支持(Determine if Platforms are Supported and Endianness)
检查平台版本以及Endian,确认是否支持我们的传输条件。如果是不同平台间的传输,本步操作必不可少。
例如:
执行查询,获取平台信息E:\ORA10G>set oracle_sid=jssweb
首先连接到源数据库。
![]()
E:\ORA10G>sqlplus "/ as sysdba"
![]()
SQL> col name heading '实例名' for a10
SQL> col version heading '数据库版本' for a15
SQL> col platform_name heading '操作系统平台' for a30
SQL> col endian_format heading '字节顺序' for a15
SQL> SELECT d.NAME, i.VERSION, d.PLATFORM_NAME, ENDIAN_FORMAT 2 FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d, V$INSTANCE i 3 WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME 4 and d.DB_UNIQUE_NAME = i.INSTANCE_NAME; 实例名 数据库版本 操作系统平台 字节顺序 ---------- --------------- ------------------------------ --------------- JSSWEB 10.2.0.1.0 Microsoft Windows IA (32-bit) Little 然后连接到目标数据库,执行同样的查询。 [oracle@jsslinux ~]$ echo $ORACLE_SID jsstts [oracle@jsslinux ~]$ sqlplus "/ as sysdba" SQL> col name heading '实例名' for a10 SQL> col version heading '数据库版本' for a15 SQL> col platform_name heading '操作系统平台' for a30 SQL> col endian_format heading '字节顺序' for a15 SQL> SELECT d.NAME, i.VERSION, d.PLATFORM_NAME, ENDIAN_FORMAT 2 FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d, V$INSTANCE i 3 WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME 4 and d.DB_UNIQUE_NAME = i.INSTANCE_NAME; 实例名 数据库版本 操作系统平台 字节顺序 ---------- --------------- ------------------------------ --------------- JSSTTS 10.2.0.1.0 Linux IA (32-bit) Little SQL>
上述查询可以得到数据库版本、操作系统平台以及ENDIAN。结合我们上节提供的传输版本对照表确认是否满足我们的传输要求。
呵呵,这里我们运气不错,虽然是两个不同的操作系统平台,但由于都采用了oracle10g,并且字节顺序相同,不仅支持跨平台传输而且还可以省掉字节转换的操作。
二、选择自包含的表空间集(Pick a Self-Contained Set of Tablespaces)
待传输的表空间集中对象可能会存在与其它对象逻辑或物理上的关联,但这里我们要强调的就是可传输的表空间集必须是自包含的,前面我们提到使用DBMS_TTS包的TRANSPORT_SET_CHECK过程来验证待传输表空间集是否自包含,TRANSPORT_SET_CHECK过程可以以两种方式执行:非严格方式和严格方式。
提示,使用sys用户执行DBMS_TTS包的过程,或者是被赋于EXECUTE_CATALOG_ROLE角色的用户。
严格方式验证就是在调用TRANSPORT_SET_CHECK过程时指定FULL_CHECK参数为TRUE。严格方式不只检查表空间集引用的对象是否自包含,同时会检查被其它表空间引用的对象,引用者是否在表空间集中。
文字太绕口,以本次演示中要传输的表空间为例。
表空间jssweb有表DEPT,其索引DEPT.IDX_DEPT_DEPTNO在users表空间。
SQL> exec dbms_tts.transport_set_check('jssweb', TRUE); PL/SQL 过程已成功完成。 SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS; 未选定行
如果表空间集满足自包含检查,则视图返回空记录。
执行严格方式的检查:
SQL> exec dbms_tts.transport_set_check('jssweb', TRUE , TRUE);
PL/SQL 过程已成功完成。
SQL> SELECT * FROM TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
--------------------------------------------------------------------------------
Index JSS.IDX_DEPT_DEPTNO in tablespace USERS points to table JSS.DEPT in tables
pace JSSWEB
不满足自包含验证,SELECT语句返回违反的信息,你可以根据其提示进行修正。
提示:如果要检查的表空间有多个,相互之间以逗号分隔即可。
三、生成可传输表空间集(Generate a Transportable Tablespace Set)
执行export操作的用户需要被赋于EXP_FULL_DATABASE 角色。
再次提示,生成可传输表空间集之前,必须将要传输的表空间置为read-only,不然你就得选择通过RMAN备份生成表空间集了。
确认所选择的表空间都是自包含之后,按照下列步骤进行操作。
1、将表空间置为READ-ONLY;
SQL> ALTER TABLESPACE JSSWEB READ ONLY;
表空间已更改。
2、使用Data Dump导出表空间集元数据
SQL> host 进入操作系统命令行 E:\ORA10G>expdp system/verysafe DUMPFILE=expdp_jssweb.dmp DIRECTORY=DATA _PUMP_DIR TRANSPORT_TABLESPACES=jssweb ..................................... ..................................... 启动 "SYSTEM"."SYS_EXPORT_TRANSPORTABLE_01": system/******** DUMPFILE=expdp_jssweb.dmp DIRECTORY=DA TA_PUMP_DIR TRANSPORT_TABLESPACES=jssweb 处理对象类型 TRANSPORTABLE_EXPORT/PLUGTS_BLK 处理对象类型 TRANSPORTABLE_EXPORT/TABLE 处理对象类型 TRANSPORTABLE_EXPORT/INDEX 处理对象类型 TRANSPORTABLE_EXPORT/CONSTRAINT/CONSTRAINT 处理对象类型 TRANSPORTABLE_EXPORT/COMMENT 处理对象类型 TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK 已成功加载/卸载了主表 "SYSTEM"."SYS_EXPORT_TRANSPORTABLE_01" ****************************************************************************** SYSTEM.SYS_EXPORT_TRANSPORTABLE_01 的转储文件集为: E:\ORA10G\PRODUCT\10.2.0\ADMIN\JSSWEB\DPDUMP\EXPDP_JSSWEB.DMP 作业 "SYSTEM"."SYS_EXPORT_TRANSPORTABLE_01" 已于 10:54:43 成功完成
这里简单介绍一下本例中调用的参数:
DUMPFILE:表示导出文件的文件名
DIRECTORY:这个DIRECTORY所指可并不是实际的物理目录哟,它是物理路径在oracle中的一个别名,这样一旦你需要调用路径就非常方便,不需要写繁长的路径,修改路径的时候也同样很方便,只需要修改directory别名这一处即可。在10g中默认创建了一个名为DATA_PUMP_DIR,其路径指向到:$ORACLE_BASE\10.2.0\admin\SID NAME\dpdump,此处我们直接引用。
TRANSPORT_TABLESPACES:对于TTS操作这是个必须指定的参数,指定要传输的表空间。
TRANSPORT_FULL_CHECK:如果你希望执行严格自包含导出的话,可以指定本参数值为Y。
EXPDP的参数还有很多,要查看其全部参数,可以通过调用expdp help=y的方式获得,如果想明确各参数的详细解释,可以参考Oracle® Database Utilities。
提示:EXPDP只是导出的待传输表空间的目录结构信息(元数据),并不包含实际数据,因此导出的速度非常快,而且文件也很小,所以千万表看到它很小,就以为导出的文件有问题。
3、如果两平台间的字节顺序不一致的话,中间需要有个转换过程,前章操作步骤里也曾深入分析过,我们此次演示中不存在字节顺序不一致的问题,所以此步跳过,留待后续展现。
