网上看到一个不错的文章,转帖给大家,包括传输表空间解决跨平台及endian-ness问题的处理方法

找到将数据从仓库迁移到集市的最快方法。


Lora是Acme银行的数据库管理员,她现在在该银行高层管理团队高级会议上成了大家最关注的核心人物。这次会议的目的是确定一些方法,来使最终用户能够详细分析公司主数据仓库中的数据。会上提出的一种想法是创建几个小型数据集市--每个集市根据一个特定的职能范围存储数据--这样每个数据集市就可以由专门的团队来使用。

为了有效地实现数据集市的方法,数据专家必须能将数据快速、有效地放入数据集市中。该团队面临的挑战就是解决如何用数据仓库中的数据快速刷新数据集市中的数据,而这些数据集市又运行在各个结构不同的平台上。这就是Lora为什么出席会议的原因。她会为移动数据提出哪些可供选择的方法呢?

作为一名经验丰富、知识渊博的数据库管理员,Lora向与会者提供了三种可能的方法,分别是:



使用可移动表空间
使用数据泵(导入和导出)
拖出表空间

本文介绍Lora对这三种可选方法的解释,包括它们的实施细节和优缺点。

可移动表空间

Lora从可移动表空方法开始介绍。把整个表空间移动到目标系统的最快速方法是用FTP(文件传输协议)或rcp(远程复制)来简单地转移表空间的基本文件。但是,仅仅复制Oracle数据文件还不够,目标数据库必须识别出并导入文件以及相应的表空间,最终用户才能使用表空间数据。使用可移动表空间包括复制表空间文件和使它们中的数据在目标数据库中可用。

在考虑该方法之前必须进行一些审查。首先,对于要转移到目标系统的表空间TS1,它必须是自含式的(self-contained)。也就是说,在该表空间中表的所有索引、分区及其他从属于该表的各数据段都必须在该表空间内部。Lora解释说,如果一个表空间集合包含所有从属的数据段,那么就认为这个集合是自含式的。例如,如果表空间TS1和TS2要作为一个集合进行转移,TS1中的一个表在TS2中有一个索引,则这个表空间集合就是自含式的。但是,如果TS1中的一个表另一个索引在表空间TS3中,则该表空间集合 (TS1, TS2)就不是自含式的。

要移动表空间,Lora提议使用Oracle数据库10g中的数据泵导出(Data Pump Export)工具。数据泵是Oracle的新一代数据转移工具,它替换了早期的Oracle Export (EXP)和Import (IMP)工具。这些老的工具使用正则SQL来提取和插入数据,而数据泵则与它们不同,它使用能绕过SQL缓冲区的专用API,从而使操作过程速度变得极快。此外,数据泵可以提取特定的对象,如特定的存储过程或特定表空间的表集合。 数据泵的导出和导入可以由作业控制,数据库管理员可以随时暂停、重启或终止这些作业。

开会前Lora运行了一项测试,看看数据泵能否解决Acme的要求。Lora进行的测试是转移TS1和TS2表空间,步骤如下:

1.检查TS1和TS2这个表空间集合是否是自含式的。执行下面的命令:



BEGIN
SYS.DBMS_TTS.TRANSPORT_SET_CHECK ('TS1','TS2');
END;

2.确定所有不可移动的集合。如果没有选择任何行,则该表空间是自含式的:


SELECT * FROM TRANSPORT_SET_VIOLATIONS;

no rows selected

3.确保该表空间是只读的:


SELECT STATUS
FROM DBA_TABLESPACES
WHERE TABLESPACE_NAME IN ('TS1','TS2');

STATUS
---------
READ ONLY
READ ONLY

4.使用传输机制,如FTP或rcp,将每个表空间中的数据文件移到远程系统,放到/u01/oradata目录下。

5.在目标数据库中,创建一个到源数据库的数据库链接(在下面的命令行中命名为srcdb)。



CREATE DATABASE LINK srcdb
USING 'srcdb';

6.在目标数据库中,使用数据泵导入工具将该表空间导入到该数据库中。


impdp lora/lora123
TRANSPORT_DATAFILES=
"'/u01/oradata/ts1_1.dbf',
'/u01/oradata/ts2_1.dbf'"
NETWORK_LINK='srcdb'
TRANSPORT_TABLESPACES=\(TS1,TS2\)
NOLOGFILE=Y

这一步就使TS1和TS2表空间以及它们的数据可以在目标数据库中可用。

请注意,Lora并没有从源数据库导出元数据。她只是在上面的impdp命令中指定参数NETWORK_LINK的值为srcdb,即到源数据库的数据库链接。数据泵导入工具通过数据库链接从源数据库中获得所需的元数据,并在目标数据库中重新创建它们。

7. 最后,使源数据库中的TS1和TS2表空间成为可读写。



ALTER TABLESPACE TS1 READ WRITE;
ALTER TABLESPACE TS2 READ WRITE;

这一步使TS1和TS2表空间在源数据库中对用户立即可用。

请注意,在前面讲的所有步骤中,最费时的是第4步,在这一步中要跨各系统移动数据文件。

跨不同平台的挑战

Lora知道,数据复制过程中的复杂因素之一就是源平台和目标平台经常不一致。例如,在Acme的环境中,当前数据仓库位于运行Tru64 UNIX的HP服务器上,而建议的数据集市将部署在运行Linux和Windows的Intel硬件上。

在Oracle数据库10g出现之前,在Acme使用可移动表空间不是一个切实可行的方法。你不能移动表空间,除非源数据库和目标数据库运行在同一个平台上。

有了Oracle数据库10g,这一限制得到了极大的缓解。在移动表空间时,数据文件可以跨各操作系统任意复制。在前面的例子中,数据文件可以从Tru64 UNIX复制到Linux或Windows,而目标数据库仍能识别它们。

但是,管理团队必须考虑另一种限制。默认情况下,只有两个操作系统具有相同的字节顺序(也被称为"endian-ness")时才可能进行跨操作系统复制。在Acme的情况下,Tru64 UNIX、基于Intel的Linux和Windows都使用little-endian字节顺序(低位在前),因此在它们之间进行文件复制是可能的。但是,有的团队成员提出了在有关数据仓库/数据集市的提案中使用Solaris操作系统的想法。Solaris使用big-endian字节顺序(高位在前),这使得在数据库之间进行简单的文件复制成为不可能。


Lora解释说,Oracle提供了使用Oracle Recovery Manager (RMAN)进行字节顺序转换的解决方案。她描述了针对RMAN解决方案的一个测试,该测试根据前面讲到的移动表空间解决方案的7个步骤,并稍作修改来适应Solaris到Intel/Linux的环境。除了在第5步之前或之后额外增加一步以外,所有操作步骤都一样。在源(Solaris)数据库服务器上执行的额外这一步如代码清单1中所示。

用这些代码,可以从Solaris格式的/u01/oradata/ts1_01.dbf文件创建Intel Linux格式的文件/u01/tts/ TS1_34。注意最初的文件并没有被破坏;只是创建了一个可以被导入和传输到Linux上的目标数据库中的新文件。

然后Lora讨论了对RMAN解决方案的一些修改。第一,为了提高性能,她可以指定PARALLELISM=子句来提高执行线程的数目。第二,她可以指定在不同的目录下以相同的文件名创建数据文件。这些修改如下:



RMAN> CONVERT TABLESPACE TS1
2> TO PLATFORM 'Linux IA (32-bit)'
3> DB_FILE_NAME_CONVERT
4> '/u01/oradata','/u01/tts'
5> PARALLELISM=4
6> ;

这条命令用相同的文件名ts1_01.dbf但在/u01/tts目录下根据原始文件/u01/oradata/ts1_01.dbf创建一个转换后的数据文件。这种方法将所有转换后的文件放到一个位置,这样确定转移哪个文件就更简单了。

Lora还可以在目标(Linux)数据库服务器而不是在源服务器上执行变换。在这种情况下,将在Linux服务器上执行转换,如下所示:



RMAN> CONVERT DATAFILE
2> '/u01/oradata/ts1_1.dbf',
'/u01/oradata/ts2_1.dbf'
3> TO PLATFORM='Linux IA (32-bit)'
4> FROM PLATFORM='Solaris[tm] OE
(64-bit)'
5> DB_FILE_NAME_CONVERT="ts","tslinux"
6> ;

这条命令通过用tslinux代替ts(换句话说,将ts1_1.dbf转换到Linux上的文件格式,新文件名为tslinux1_1.dbf)来创建文件。在数据库内,文件将用这个文件名。

Lora怎么知道哪个平台用哪种字节顺序呢?在数据字典视图上执行以下查询就会给出答案:



SELECT * FROM V$TRANSPORTABLE_PLATFORM ORDER BY PLATFORM_ID;

数据泵导出与导入工具

选择可移动表空间的限制之一是在转移文件时源表空间必须是只读模式。在现实世界中,并不总是能满足这一要求。例如,在OLTP数据库中,可能对表要经常进行读写操作。

Lora提出的另一种方法是使用Oracle数据库10g中的数据泵实用工具来转移表空间。她对这种方法进行的测试包括移动TS1和TS2表空间内容的以下步骤:

1.创建一个目录对象来存放转储的文件。



CREATE DIRECTORY dump_dir AS '/u01/dumps';

2.用数据泵导出工具导出数据。


expdp lora/lora123 TABLESPACES=\(ts1,ts2\) DUMPFILE=ts1_ts2.dmp DIRECTORY=dump_dir

这一步创建一个包含TS1和TS2表空间内容的文件/u01/dumps/ ts1_ts2.dmp。

3.将文件ts1_ts2.dmp转移到远程系统中,放在目录/u01/dumps下(用文件传输的方法如FTP或rcp)。

4.在目标数据库中创建一个目录对象。



CREATE DIRECTORY dump_dir
AS '/u01/dumps';

5.使用数据泵导入工具将该文件导入到该数据库中。


impdp lora/lora123 DIRECTORY=dump_dir DUMPFILE=ts1_ts2.dmp

如果表空间内的数据量相对较小,则Lora可以只用一条命令执行上面的所有步骤:


impdp lora/lora123 DIRECTORY=dump_dir NETWORK_LINK='srcdb' TABLESPACES=\(ts1,ts2\)

这条命令使用数据泵导入工具将通过数据库链接srcdb(在以前的章节中已讨论过)检索到的数据加载到表中。但是,由于网络带宽通常是受到限制的,因此这种方法可能比使用导出/传输/导入周期方法要慢一些。

如果只需将特定的表或表集合进行转移,那么Lora可以在expdp命令中使用TABLES=子句来只下载特定的表或表集合。

拖出表空间

作为第三种选择,Lora建议使用Oracle数据库10g中的新工具,它简化了可移动表空间的移动方法,因此只涉及执行一个打包过程。在这种方法中,用户利用所提供的DBMS_STREAMS_TABLESPACE_ADM包从源系统中"拖?quot;表空间。这个包使用数据泵转移表空间并将数据文件转换成目标系统的格式。 它还自动执行任何所需的字节顺序变换。

下面给出在最简单的情况下使用这种方法的过程--涉及单个简单表空间(更复杂的情况在下一节介绍)。 如果一个表空间只有一个数据文件,则这个表空间称为简单表空间。Lora演示了DBMS_STREAMS_TABLESPACE_ADM包中PULL_SIMPLE_TABLESPACE过程的使用方法:

1.在存放数据文件的目录所在的(远程)数据仓库数据库中创建一个目录对象。



CREATE DIRECTORY dbf_dir AS '/u01/oradata/dw';

2.设置远程数据库中的表空间TS1为只读。


ALTER TABLESPACE TS1 READ ONLY;

剩下的一些步骤在本地(数据集市)数据库中完成。

3.创建一个连接到远程(数据仓库)数据库(在Lora的例子中是dwdb)的数据库链接。



CREATE DATABASE LINK dwdb USING 'dwdb';

4.创建一个数据文件将被转移到其中的目录对象。


CREATE DIRECTORY dbf_dir AS '/u01/oradata/mart';

5.从远程数据库中拖出表空间。


BEGIN
DBMS_STREAMS_TABLESPACE_ADM
.PULL_SIMPLE_TABLESPACE (
tablespace_name => 'TS1',
database_link => 'dwdb',
directory_object => 'DBF_DIR',
conversion_extension => 'linux'
);
END;

该操作在后台完成了许多步骤:设置源表空间为只读;用数据泵导出工具进行一次表空间的元数据转储;用DBMS_FILE_TRANSFER包移动数据文件和转储的文件;把源表空间恢复到其最初的读写状态;使用数据泵导入工具将表空间插入到本地数据库中。由于源数据库运行在Linux上,而目标数据库运行在Solaris上,因此这一操作首先复制原始数据文件(Linux的文件格式),然后将它转换到目标平台上(Solaris)的文件格式。复制过程保持最初被转移的文件,而创建一个新文件用于转换。新文件与最初的文件同名,但具有CONVERSION_EXTENSION参数指定的linux扩展名。在目标数据库中创建的表空间为只读表空间。

该操作还在与数据文件相同的目录下创建一个名为ts1_01.plg的日志文件。如果执行该过程返回错误信息,则检查该文件的内容可能有助于找到错误的原因。

拖出多个表空间


上面的例子针对的是单个简单表空间的情况。但如果Lora想移动一组表空间,或者一些表空间的数据文件多于一个,该怎么办呢?在这种情况下,她可以使用同一个包中的另一个过程PULL_TABLESPACES。代码清单2给出的例子说明Lora如何转移两个表空间TS7和TS8,而不管它们有多少个数据文件。

该过程要求以VARCHAR2数据类型给出表空间名和目录名。代码清单2中第2行到第5行展示出了这些变量的声明,第10行到第13行展示出这些变量被赋值给相应的表空间名和目录名。 由于定义了两个目录,因此第一个文件在第一个目录中创建,下一个文件在第二个目录中创建,第三个文件再次在第一个目录中创建,如此等等。这些操作通过数据泵作业来执行,作业名在第17行指定。如果需要的话,源系统字节顺序的数据文件会自动转换为目标系统的字节顺序。在目标数据库中创建的新文件获得linux扩展名,如第21行代码所示。处理过程记录在由目录对象LOG_DIR指定的目录中的ts7_ts8.log日志文件中(第14行)。

这种方法的优点显而易见。从一个系统把一个表空间转移到另一个系统所需的所有操作任务都封装在一个程序单元中,并且细节对用户完全透明。甚至把文件从源系统转移到目标系统的工作也在这个过程中通过所提供的DBMS_FILE_TRANSFER包来完成。用户简单地用表空间名调用该过程,表空间就会在本地数据库中被刷新。他们不必操心底层的细节(如操作系统),因为文件转移过程自动转换文件。这种方法有什么不好的地方吗?会上Lora讲到,它的主要缺点就是将各个功能封装在一个单一的过程内,这可能会掩盖某一步产生的错误,使问题的诊断变得很复杂。手工转移一个表空间的方法要求各条命令都是透明的,因而其好处是用户能够看到每一步操作的结果。

会议结束

针对Acme的数据仓库/数据集市体系结构,Lora提出了几种移动数据的可选方法。

第一种可选方法是使用可移动表空间,它能移动完整的表空间集合(不仅包括表,还包括索引、物化视图和其他对象)。通常它还是这三种方法中最快的一种。但是,它的一个主要缺点是对指定的表空间必须在复制文件时设置为只读。

第二种方法是使用数据泵,它对表空间是否为只读没有要求。当只需要移动指定的表而不是整个表空间时,这种方法很有用。

最后一种方法是拖出表空间,该方法把可移动表空间方法的所有步骤组合成一步操作。用这种方法复制数据非常简单,但要想调整每个具体步骤以便进行性能优化时,它为数据库管理员提供的灵活性太少。

在会议结束时,高级管理层对Lora表示感谢,而Lora也感谢高级管理层对Acme银行迁移到Oracle数据库10g的支持,因为这使得不同的数据移动方法都成为可行的。