Chinaunix首页 | 论坛 | 博客
  • 博客访问: 143984
  • 博文数量: 161
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -30
  • 用 户 组: 普通用户
  • 注册时间: 2017-09-21 21:45
文章分类
文章存档

2009年(1)

2008年(74)

2007年(48)

2006年(38)

我的朋友

分类: Oracle

2008-07-30 15:29:20

第 16 周
可传输表空间

可传输表空间现在可以跨平台移植,从而使得数据发布更快更容易。此外,外部表下载使得通过转换进行数据转移的任务更简单更快。

您如何将数据从一个数据库转移到另一个数据库?在现有的几种方法中,有一种方法尤为出色:可传输表空间。在这种方法中,您使用一组自包含、只读的表空间,只导出元数据,在操作系统层将这些表空间的数据文件拷贝至目标平台,并将元数据导入数据字典 — 这个过程称为插入

操作系统文件拷贝一般比其它传统的数据转移方法(如导出/导入或 SQL*Loader)要快得多。然而,在 Oracle9i 数据库和更低版本中,可传输表空间仅限于在目标数据库和源数据库都运行在同一操作系统平台上的少数情况下才有用 — 例如,您不能在 Solaris 和 HP-UX 平台之间传输表空间。

在 Oracle 数据库 10g 中,这个局限消失了:只要操作系统字节顺序相同,您就可以在平台之间传输表空间。本文将不就字节顺序展开长篇的讨论,但这里只要提几句话就足够了:一些操作系统(包括 Windows)在低位内存地址中用最低有效字节存储多字节二进制数据;因此这种系统被称为低地址低字节序。相反,其它的操作系统(包括 Solaris)将最高有效字节存储在低位内存地址中,因此这种系统被称为低地址高字节序。当一个低地址高字节序的系统试图从一个低地址低字节序的系统中读取数据时,需要一个转换过程 — 否则,字节顺序将导致不能正确解释读取的数据。(有关字节顺序的详细说明,请阅读嵌入式系统编程的 2002 年 1 月刊中的一篇极好的文章。)不过,当在相同字节顺序的平台之间传输表空间时,不需要任何转换。

您怎么知道哪一种操作系统采用哪一种字节顺序?不需猜测或搜索互联网,相反只需简单地执行以下查询:
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

假设您想从一台在 Intel 体系结构上运行 Linux 操作系统的主机 SRC1 中将一个表空间 USERS 传输到运行 Microsoft Windows 操作系统的计算机 TGT1 上。源平台和目标平台都是低地址低字节序的。表空间 USERS 的数据文件是 users_01.dbf。您将按照类似以下的方法来进行操作。
  1. 使表空间为只读:
    alter tablespace users read only;
  2. 导出表空间。在操作系统提示符下执行:
    exp tablespaces=users transport_tablespace=y file=exp_ts_users.dmp
    exp_ts_users.dmp 文件只包含元数据(不是表空间 USERS 的内容)因此它将非常小。

  3. 将文件 exp_ts_users.dmp 和 users_01.dbf 拷贝至主机 TGT1。如果您使用 FTP,那么您将需要指定二进制选项。
  4. 将表空间插入到数据库中。在操作系统命令提示符下执行下面的语句:
    imp tablespaces=users transport_tablespace=y file=exp_ts_users.dmp datafiles='users_01.dbf'
在第 4 步之后,目标数据库将有一个名称为 USERS 的表空间,并将提供该表空间的内容。

请记住,系统 SRC1 和 TGT1 分别是 Linux 和 Windows。到 Oracle9i 为止,运行在 TGT1 上的数据库不能识别第 4 步中的数据文件 users_01.dbf,从而使得整个过程无用。您将必须求助其它一些方法(如常规的导出和导入、创建纯文本文件并通过 SQL*Loader 加载,或直接在不同的数据库间连接加载插入)。

在 10g 中,不再需要这些替代方法,因为目标数据库能够识别来自另一个平台的数据文件。在我们的示例中,源主机和目标主机运行的操作系统的字节顺序是相同的(低地址低字节序),因此不需要任何转换。

这个功能在数据仓库中特别有用,其中更小的面向对象的数据集市常常在刷新之后从仓库中进行填充。利用 10g,这些数据集市现在能够放在更小、更廉价的计算机(如运行 Linux 的 Intel boxes)中,而将数据仓库服务器放在更大的企业级计算机中。从本质上讲,利用可传输表空间,您现在可以更好地利用各种硬件和操作系统的组合。

跨不同字节顺序的平台

如果平台是不同字节顺序的,那么您将如何实现可传输性?正如我之前说明的,目标计算机的字节顺序如果与源计算机的字节顺序不同,那么将不能正确地读取数据文件,因而不可能简单地拷贝数据文件。但别灰心,在 Oracle 10g RMAN 实用程序中提供了帮助,它支持将数据文件从一种字节顺序向另一种字节顺序转换。

在上面的例子中,如果主机 SRC1 运行在 Linux 上(低地址低字节序),而目标主机 TGT1 运行在 HP-UX 上(低地址高字节序),那么您需要在第 3 步和第 4 步之间引入另一个步骤,以进行转换。利用 RMAN,您将在源计算机 SRC1 上把数据文件从 Linux 转换成 HP-UX 格式(假定您已经使表空间变为只读):
RMAN> convert tablespace users
2> to platform 'HP-UX (64-bit)'
3>  format='/home/oracle/rman_bkups/%N_%f';

Starting backup at 14-MAR-04
using channel ORA_DISK_1
channel ORA_DISK_1:starting datafile conversion
input datafile fno=00004 name=/usr/oradata/dw/starz10/users01.dbf
converted datafile=/home/oracle/rman_bkups/USERS_4
channel ORA_DISK_1:datafile conversion complete, elapsed time: 00:00:07
Finished backup at 14-MAR-04

这个步骤在目录 /home/oracle/rman_bkups 中创建了一个标准 RMAN 文件格式 _ 的文件。注意我们没有触及表空间 USERS 的数据文件;而是为 HP-UX 创建了一个新文件。现在可以将这个文件拷贝至目标系统,剩下的步骤很简单。

这个 RMAN 转换命令非常强大。按照上面给定的形式,它可以按顺序创建数据文件。对于包含多个数据文件的表空间,您可以命令同时转换并运行多个数据文件。要实现这一目的,您将需要在上述命令中添加一个子句:
parallelism = 4

该子句创建四个 RMAN 通道,每一个通道处理一个数据文件。不过,一种更有用的方法是用一个步骤转换大量的表空间,在这种情况下并行转换将真正带来很大的帮助。下面我们将两个表空间 USERS 和 MAINTS 转换至 HP-UX:
RMAN> convert tablespace users, maints
2> to platform 'HP-UX (64-bit)'
3> format='/home/oracle/rman_bkups/%N_%f'
4> parallelism = 5;

Starting backup at 14-MAR-04
using target database controlfile instead of recovery catalog
allocated channel:ORA_DISK_1
channel ORA_DISK_1:sid=244 devtype=DISK
allocated channel:ORA_DISK_2
channel ORA_DISK_2:sid=243 devtype=DISK
allocated channel:ORA_DISK_3
channel ORA_DISK_3:sid=245 devtype=DISK
allocated channel:ORA_DISK_4
channel ORA_DISK_4:sid=272 devtype=DISK
allocated channel:ORA_DISK_5
channel ORA_DISK_5:sid=253 devtype=DISK
channel ORA_DISK_1:starting datafile conversion
input datafile fno=00004 name=/usr/oradata/dw10/dw10/users01.dbf
channel ORA_DISK_2:starting datafile conversion
input datafile fno=00005 name=/usr/oradata/dw10/dw10/users02.dbf
channel ORA_DISK_3:starting datafile conversion
input datafile fno=00006 name=/usr/oradata/dw10/dw10/maints01.dbf
channel ORA_DISK_4:starting datafile conversion
input datafile fno=00007 name=/usr/oradata/dw10/dw10/maints02.dbf
converted datafile=/home/oracle/rman_bkups/USERS_4
channel ORA_DISK_1:datafile conversion complete, elapsed time: 00:00:03
converted datafile=/home/oracle/rman_bkups/USERS_5
channel ORA_DISK_2:datafile conversion complete, elapsed time: 00:00:00
converted datafile=/home/oracle/rman_bkups/MAINTS_6
channel ORA_DISK_3:datafile conversion complete, elapsed time: 00:00:01
converted datafile=/home/oracle/rman_bkups/MAINTS_7
channel ORA_DISK_4:datafile conversion complete, elapsed time: 00:00:01
Finished backup at 14-MAR-04

在上述例子中,转换后的文件名难于辨认并很难与原始文件关联(例如,文件 users01.dbf 变为 USERS_4)。相反,您还可以使用其它格式来为数据文件命名。这个过程类似于在 Data Guard 中为数据文件重命名的过程。您可以使用如下命令:
RMAN> convert tablespace users
2> to platform 'HP-UX (64-bit)'
3> db_file_name_convert '/usr/oradata/dw10/dw10','/home/oracle/rman_bkups'
4> ;

Starting backup at 14-MAR-04
using channel ORA_DISK_1
channel ORA_DISK_1:starting datafile conversion
input datafile fno=00004 name=/usr/oradata/dw10/dw10/users01.dbf
converted datafile=/home/oracle/rman_bkups/users01.dbf
channel ORA_DISK_1:datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1:starting datafile conversion
input datafile fno=00005 name=/usr/oradata/dw10/dw10/users02.dbf
converted datafile=/home/oracle/rman_bkups/users02.dbf
channel ORA_DISK_1:datafile conversion complete, elapsed time: 00:00:01
Finished backup at 14-MAR-04 

这将在转换后保留文件名。如果您切换到目录 /home/oracle/rman_bkups,您将看到文件 users01.dbf 和 users02.dbf,它们对应相同名称的原始文件。

在上述情况下,我们在源平台上转换文件。不过,您也可以在目标平台上转换文件。例如,您可以将文件 users01.dbf 拷贝至运行 HP-UX 的主机 TGT1 上,然后利用以下命令将文件转换成 HP-UX 格式:
RMAN> convert
2> datafile '/usr/oradata/dw10/dw10/users01.dbf'
3> format '/home/oracle/rman_bkups/%N_%f'
4> ;

这种方法将以指定的格式在目录中创建文件。

但为什么您会想在目标平台上转换数据文件,确切的原因是什么?一个原因是更短的停机时间,这要求表空间仅在拷贝至目标主机期间为 READ ONLY 状态。您可以为数据文件创建三个镜像,使表空间为只读,分开第三个镜像,然后立即使表空间为读/写状态。然后可以把第三个镜像加载到目标系统上,并在空闲时进行转换。这种安排使得表空间必须保持为只读的时间最少。

另一个原因可能是性能。OLTP 数据库可能承担一个持续的负载,而使用 RMAN 转换操作可能使系统负载超出期望的范围。相反,可以把转换操作卸载到数据仓库服务器上,其中通常提供了更多的 CPU,以进行并行操作。

将外部表用作数据传输机制

Oracle9i 数据库引入了外部表,外部表使得格式化的纯文本文件在数据库中视为一个表,此表可以通过常规 SQL 进行选择。假设您必须使用这种外部表方法将名称为 TRANS 的表的内容从 OLTP 数据库转移到数据仓库数据库中。下面是实现这一目的的步骤。
  1. 从 OLTP 数据库中,使用表 TRANS 的内容创建一个纯文本文件。该文件可以在目录 /home/oracle/dump_dir 中命名为 trans_flat.txt。该文件通常是用这条 SQL 语句创建的:
    spool trans_flat.txt
    select  ||','||  ||','|| ...
    from trans;
    spool off
  2. 利用 ftp、rcp 或其它一些机制将文件拷贝至数据仓库服务器中。该文件位于目录 /home/oracle/dump_dir 中。
  3. 在数据仓库数据库上,创建一个名称为 dump_dir 的目录对象,方法如下:
    create directory dump_dir as '/home/oracle/dump_dir';
  4. 创建一个外部表:
    create table trans_ext
    (
    ...  ...
    )
    organization external
    (
    type oracle_loader
    default directory admin
    access parameters
       (
    records delimited by newline
    badfile 'trans_ext.bad'
    discardfile 'trans_ext.dis'
    logfile 'trans_ext.log'
    fields terminated by ","  optionally enclosed by '"'
          (
    ...  ...
          )
       )
    location ('trans_flat.txt')
    )
    reject limit unlimited;
  5. 现在利用任意一种常用的方法(如直接加载插入和合并)将外部表加载到常规表中。
这里最费时的操作是第 1 步,在这个步骤中创建了纯文本文件。您可以使用纯 SQL 来创建这个文件,然后假脱机到一个文件 — 一个简单但却漫长的过程。您可以使用 Pro*C 或 OCI 程序(替代 SQL*Plus)来将记录卸载到一个纯文本文件中,以使这个过程稍微快一些,但它仍将花费一段时间。另一个“速度障碍”是需要人工指定列 — 又一个费时的过程。

这两个问题在 10g 中都已得到了解决。现在您可以利用外部表创建过程快速地将一个表卸载成可移植的格式。上面的第 1 步变为这条简单的 SQL 语句:
create directory dump_dir as '/home/oracle/dump_dir';

create table trans_dump
organization external
(
type oracle_datapump
default directory dump_dir
location ('trans_dump.dmp')
)
as
select * from trans
/

这些命令在目录 /home/oracle/dump_dir 中创建了一个名称为 trans_dump.dmp 的文件。这个文件不完全是 ASCII 文本;元数据是纯文本,但实际的数据是原始格式的。不过,这个文件是可以移植到不同的操作系统 — 类似于导出转储文件,但与导出不同的是,数据下载非常快。您将把这个文件拷贝到数据仓库服务器中,然后用与之前提到的相同的方式创建外部表,但这次用这个文件替换源文件。

那么旧的数据传输机制和这种数据传输机制有什么不同?有一些不同。首先,您可以非常快速地创建一个可移植的文件,而无需编写任何复杂的 SQL,选择表的列等等。其次,您可以用这种文件作为外部表的输入,从而使得将数据作为一个常规的表进行查看并在数据处理之后将数据加载到其它的表中成为可能。您还可以按如下所示方法提高到这种外部表中的数据下载的性能。
create table trans_dump
organization external
(
type oracle_datapump
default directory dump_dir
location ('trans_dump.dmp')
)
parallel 2
as
select * from trans
/
这些命令创建了相同的文件,只不过是以并行的方式。您应当这么做,以利用多个主机 CPU(如果提供的话)。除了并行化之外,您还可以按照如下所示方法将表下载到多个外部文件中。
create table trans_dump
organization external
(
type oracle_datapump
default directory dump_dir
location ('trans_dump_1.dmp','trans_dump_2.dmp')
)
parallel 4
as
select * from trans
/

这些命令创建了两个文件 trans_dump_1.dmp 和 trans_dump_2.dmp,而不只是一个。这种方法在将文件扩散到多个物理设备或控制器上以减少与 I/O 相关的等待时非常有帮助。

结论

通过使表空间能够跨平台传输,10g 为数据仓库数据转移提供了一个强大的解决方案。该特性与外部表下载相结合,消除了在源数据库和目标数据库之间进行数据发布的阻碍(无论它是 OLTP 数据库、数据仓库数据库或数据集市数据库)并使您能够为特定类型的应用程序作出适当的平台选择。

此外,通过使可传输表空间变得可行,10g 使得数据刷新更快更频繁,以便能够更快地把经过分析的数据提供给最终用户。该功能还可以用来通过离线介质将数据发布给不同的数据库,而不管它们的主机系统是什么。利用外部表下载,终于为最终用户提供了一个作为 ETL 工具的实用程序,以用来转移大量的数据。

有关 10g 中的传输表空间的更多信息,请参见 的第 8 章的一节。
阅读(545) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~