日期:2014-05-16  浏览次数:20451 次

缩短Oracle数据库迁移过程中的停机时间

使用导出/导入方法执行快速应用程序数据库迁移的步骤顺序

在本例中,我们不过分注重导出/导入或数据库连接的详细步骤,也不过分注重并行处理,我们把注意力集中在以下方法上:首先在系统运行期间仅把数据结 构迁移到新系统上,然后在系统停机时间仅迁移数据。导出/导入的其他参数(比如direct、buffers和log等)对于调节所用工具性能和行为是必 需的。根据数据量和允许的停机时间长度,这个数据迁移过程可能需要经历更多阶段。

1. 将源数据库的逻辑结构迁移到目标数据库上(可在迁移之前完成,不需要停机)

* 仅从源数据库导出数据库结构(表、索引、约束限制定义、PL/SQL存储过程等);
命令如下:exp sys/password file=structure.dmp rows=n indexes=y constraints=y full=y
* 导入数据库结构至目标数据库,不包含约束限制和索引;
命令如下:imp sys/password file=structure.dmp constraints=n indexes=n full=y

这些操作不需要太多的调节,因为它们都能在系统运行期间来执行。

2. 仅将数据从源数据库导入至目标数据库(当源数据库准备好升级后执行该步骤,需要系统停机)

* 为了保留数据一致性,我们必须确保没有任何人可以再改变数据库,这通常意味着关闭应用程序服务器和任何接口并把数据库设置成限制模式。
* 从源数据库中仅导出数据库表的行;
命令如下:exp sys/password file=data.dmp rows=y constraints=n indexes=n full=y
* 从导出文件仅导入数据库表的行;
命令如下:imp sys/password file=data.dmp constraints=n indexes=n full=y ignore=y

不导入约束限制和索引是为了在数据载入期间避免临时数据的不一致性和索引维护性能问题。在所有数据成功迁移后,再建立索引和约束限制。

以下是一些其他导出/导入参数,它们能提高数据迁移的性能:

参数???????????????????? 注释

direct????????????????? 如果设置成Y,使得导出/导入绕过常规的SQL机制并从数据文件中直接导入数据,因此速度非常快。
限制条件:在Oracle 8.1.5以前,含有大对象或对象字段的行不被导出,必须使用常规方法。客户端字符集(通过NLS_LANG参数来设置)必须和数据库的字符集匹配。

Recordlength??????????? 单位是字节,指定一次请求可以写入“导出文件”或者从“导出文件”读的数据的量。最大值是65536(64kB),默认值是特定于操作系统的,通常是1kB。正常情况下,64kB是最优的。

Buffer????????????????? 仅使用于传统的路径导出和导入(direct=n)。指定“取缓冲区”的大小,单位是字节。它决定了导出时一次可取的数组的最大行数,和导入时的最大插入数组的大小。

Commit????????????????? 默认值是N,意指仅在每个表(或者表的中间部分)的结尾处进行提交。当导入很大的表并且没有足够的回滚空间时,应该把该参数设置成Y,但是,缓冲区的大小应该被设置的足够大从而避免“过度提交”带来的性能问题。

作为替代方法,在数据库连接上使用“并行直接载入插入法”来迁移非常大的表。

因为将几十GB的数据库表导出到磁盘上并从磁盘上再导回到新数据库中可能不可行,可以使用“并行直接载入插入法”。在数据库连接上使用“并行直接载入插入法”可能比导出/导入法快很多,由于数据不需要被过渡存储,而是通过网络直接转移的。

命令如下:
alter session enable parallel dml;
alter table table_name nologging;

insert /*+ APPEND PARALLEL(table_name,4) */
into table_name select * from table_name@dblink;

alter table table_name logging;

不要忘记将表或表空间重新设置回“日志模式”。从Oracle 9i开始,你可以再插入命令中使用NOLOGGING暗示参数,那样的话你根本就无需手动更改表或表空间至“关闭日志”状态。

命令如下:
insert /*+ APPEND NOLOGGING PARALLEL(table_name,4) */
into table_name select * from table_name@dblink;

上面的PARALLEL暗示参数仅指出插入本身将被并行执行。为了使用并行查询从源数据库从析取出数据,我们可以给select语句也增加一个PARALLEL暗示参数,但是通常情况下这并没有任何帮助,由于全表扫描的最简单本质-即,磁盘输入输出和网络往往是瓶颈所在。

命令如下:
insert /*+ APPEND NOLOGGING PARALLEL(table_name,4) */
into table_name
select /*+ PARALLEL(table_name,4) */ from table_name@dblink;

参见附录C中的对相关联表创建插入和更新命令的简单脚本。

* 在存储局域网环境中,可以使用分离镜像技术或者类似EMC系统上的“业务连续卷”在一个临时服务器上打开数据库的一个精确拷贝,从而拥有多个源环境可以载 入数据。当从旧的速的慢的系统迁移数据到新的快速系统时,这种技术可以加速数据迁移。该技术需要在产品升级期间临时使用一个具有相同操作系统和平台的服务 器。需要对表或模式名作出区分,以便可以从一个服务器上导入一部分数据,同时从其他的服务器上导入其他数据。

你可以组合上述方法来迁移模式对象,比如对小表和模式使用导出/导入方法,而对大表使用在数据库连接上使用“并行直接载入插入法”。

3.创建索引并激活约束限制(需要系统停机)

* 第一种方法:使用前面所述的导出结构文件来顺序创建索引和约束限制

命令如下:
imp sys/password file=structure.dmp constraints=y indexes=y full=y ignore=y

这种方法有问题-使用导入方式,我们实际上不能指定并发的自定义级别来创建索引,也不能指定NOLOGGING属性。即使我们使用不在正式文件中记 录的特殊参数来关闭对磁盘的重做写操作,NOLOGGING属性仍然能提高性能,通过设置更少的检测点和使用更少的CPU。幸运地,存在一个可以绕过这个 问题的导入特性,它运行我们从导出文件中析取出索引创建脚本。

* 第二种方法:使用导入操作的indexfile选项单独创建索引,然后按照通常方式使用导入创建约束限制。

很长的索引创建时间可以被极大地缩短,当使用并行执行方式和属性nologging时。由于导入的语法本身不允许我们指定创建索引的方式,我们不得不先得到索引创建脚本,然后根据我们的实际需要修改它们。导入的indexfile选项使用起来非常便利,如下所示:

命令如下:
imp sys/password file=structure.dmp constraints=y indexes=y full=y ignore=y \
? show=y indexfile=indexes.sql

上面的例子对单独的和约束索引创建都产生了SQL 数据定义语言(DDL)命令(对于关键约束限制和唯一约束限制,一些索引也暗含被创建)。请注意参数show=y,它指定了不能对数据库做改变,导出文件 仅仅是从头至尾扫描一遍,其间发生的任何索引创建都被存储到使用indexfile选项指定的indexes.sql脚本中。

接下来,我们可以使用一个文本编辑器打开这个SQL脚本,然后用NOLOGGING代替LOGGING并对每个大索引创建命令添加PARALLEL 子句。我们也可以在脚本开始处使用更改会话命令来修改某些参数,比如sort_area_size 和 db_file_multiblock_read_count,这两个参数能极大地增加创建索引的速度(更多信息请参见数据库性能调优部分)。修改好以 后,使用sqlplus来运行该脚本。

命令如下:
sqlplus sys/password @indexes.sql

索引文件(indexfile)包含独立索引和外键约束或唯一性约束所需的索引,但是不包含约束限制定义本