DB2 Universal Database 与 Oracle 的数据移动
比较指南
级别: 初级
Allan W. Tham (thamawh@my.ibm.com), DB2 售前技术专家, ASEAN Techline
2005 年 5 月 05 日
如果您具有 Oracle 方面的经验,现在开始学习 DB2® Universal Database™,那么本文将帮助您利用以前的经验,并教您快速提升之道,以了解如何从一台机器到另一台或者从一种平台到另一种平台移动数据。
两个数据库之间的数据移动是 DBA 的普通日常工作。大多数成熟的数据库提供了从一个数据库到同一平台或机器中的另一数据库,或者到其他平台或机器的另一个数据库移动数据的方法。
如果您具有 Oracle 方面的经验,并且现在开始学习 DB2,那么本文将简化您的学习过程。其意图就是使 Oracle DBA 在记住这两者的区别时,快速提升 DB2 Universal Database(DB2 UDB)的经验。我们将介绍执行数据移动所需的工具和命令,并比较和对照这两种数据库系统。此外,还要来看一些进行数据移动的场景。
注意,本文不会介绍用于数据移动的复制机制,例如 Oracle Advanced Replication 和 数据复制走上快车,也不会考虑使用通过 JDBC、PERL DBI 和 ODBC 的定制编码获得的连通性或数据移动,因为这些接口不用于移动大量数据。
本文着重介绍这两种数据库所提供的数据移动实用程序及其特性和功能。同时,我们还将考虑每个实用程序或方法的利弊。本文将涉及下列主题。在考虑这些主题时,我们要来看一些场景,以便更好地理解每个实用程序的特性和功能。
- 导入
- 导出
- 工具比较
- 快速基准测试
- 其他可用工具
- 数据移动场景
在特殊的某一天,DBA 可能要参与管理工作,例如将数据文件移动到生产机器上更大的文件系统中,为测试目的创建生产数据的一个子集,或复制整个数据库用于开发。通过在开发机器上复制数据集,开发人员可以测试并丢弃数据,而无需担心其结果。每当需要一个新的数据集时,简单的恢复就可以使数据返回其初始状态,以进行另一测试循环。
在涉及万亿字节(TB)的环境中,特别是在仓库环境中,为测试目的复制整个数据库是不可行的。本例中,您可能需要一个数据子集,并具有完好的参照完整性。同时,您还可能需要为操作应用程序模块的开发人员在测试机器中部署多个合适的数据集。在完成测试时,经常必须将数据移至生产中。
进行数据移动的另一理由可能是出于各种原因需要将数据库迁移至一个新的平台。
下面总结了一些最常见的数据移动场景:
- 在当前文件系统已满时,将数据文件移至另一文件系统。
- 出于测试/开发目的,移动整个数据库或数据库子集。
- 将数据库从一个平台迁移到另一个平台。
DBA 通常基于数据库的大小、维护窗口和诸如网络/IO、CPU/内存这样的系统资源来选择数据移动的方法。在下一小节中,我们将考查进行数据移动的各种方法。
导入实用程序
首先,我们将介绍 Oracle 为数据导入所提供的实用程序。Oracle 提供了下列实用程序以导入数据:
- Oracle - imp
- Oracle - SQL Loader
Oracle 导入实用程序 imp 已经存在相当长一段时间了。imp 实用程序用于导入中小型数据库,例如大小在 100 MB 到 10 GB 之间。为了加快导入过程,您可以一次使用多个 imp 作业。而为了使用 imp,首先必须运行驻留在 /rdbms 目录中的 catalog.sql 脚本或 catexp.sql 脚本。
为了使用导入实用程序,需要包含在角色 CONNECT 中的权限 CREATE SESSION。
其中涉及两种导入模式(import schema)的方式:
- 导入同一用户模式 -
若要将对象导入同一用户模式,需要将系统和对象权限都授予给该用户,特别是 RESOURCE 角色。 - 导入其他用户模式 -
数据库对象可以由一个用户导出,而由其他用户导入。如果导入另一模式,就必须启用 IMP_FULL_DATABASE 角色。
清单 1 中显示了执行导入的语法。关于所有参数的完整解释,请查阅 Oracle Utility Guide,或者就从命令提示符发出 imp help=y。
清单 1. Oracle imp 的语法
imp keyword=value [,keyword=value,...] where keywords are USERID username/password BUFFER size of data buffer FILE input files (EXPDAT.DMP) SHOW list file contents (N) IGNORE ignore create errors (N) GRANTS import grants (Y) INDEXES import indexes (Y) ROWS import data rows (Y) LOG log file of screen output FULL import entire file (N) FROMUSER list of owner usernames TOUSER list of usernames TABLES list of table names RECORDLENGTH length of IO record INCTYPE incremental import type COMMIT commit array insert (N) PARFILE parameter filename CONSTRAINTS import constraints (Y) |
或者,您可以用命令 imp help=y 获得在线帮助。
有三种方法调用 imp 实用程序:
- 命令行
例如:imp system/password fromuser=scott touser=scott file=acct_pay.dmp
图 1. 使用命令行调用 Oracle 导入实用程序
- 带有 parfile 选项的命令行
例如:imp system/manager parfile=Acct_Pay.txt
图 2. 使用带有 parfile 参数的命令行调用 Oracle 导入实用程序
- 命令行交互
图 3. 交互调用 Oracle 导入实用程序
一共有 4 种不同的导入方式。下面,您将看到一些使用导入实用程序的例子。在开始考查这些例子时,您将看到很多重要的考虑因素。例如,为了尽可能减少错误,最好使用 CONSTRAINTS=N 来禁用参照完整性。在导入结束时,将启用约束。同时,还应禁用触发器。在导入完成后,DBA 通常执行一个脚本来生成这些触发器。
只有 Oracle exp 实用程序所生成的导出转储(dump)可以使用。较高版本的 imp 可以读取相同或更低版本的导出转储。然而,当试图从较低版本的导出实用程序导入转储文件时,将发生错误。
以下是 4 种导入方式的例子:
- 全导入 - FULL=Y。
若参数 FULL=Y,那么将导入所有之前使用 FULL=Y 所导出的对象。为了确保可以成功执行全导入,要注意一些步骤。有关更多细节,请查阅 场景 小节。 - 用户级导入 - FromUser 和 Touser
例如,要导入用户模式 scott 的所有对象,就发出命令: imp system/password fromuser=scott Touser=allan file=Acct_Pay.dmp。
图 4. 使用 Fromuser 和 Touser 参数进行导入
- 表级导入 - Tables = (*)
- 使用 Table = (*) 进行导入。例如,要导入模式 Scott 中的所有表,就发出命令: imp system/password fromuser=scott touser=allan file=Acct_Pay.dmp tables=(*)。
图 5. 导入所有表
- 使用 Tables = (A, B, C) 进行导入。例如, imp system/password fromuser=scott touser=allan file=Acct_Pay.dmp tables=(BONUS,EMP) constraints=N。
图 6. 导入所选择的表
- 导入分区表,Tables = (T:p1, T:p2) - 例如,imp scott/tiger file=Scottt.dmp tables=(empp:p1, empp:p2)。
图 7. 导入分区表
- 使用 Table = (*) 进行导入。例如,要导入模式 Scott 中的所有表,就发出命令: imp system/password fromuser=scott touser=allan file=Acct_Pay.dmp tables=(*)。
- 表空间级导入 - Transport_Tablepspace = Y、Tablespaces=(A,B,C) 和 Datafiles=xxx。有关 Oracle 的表空间级导入的更多细节,请查阅 场景 小节。
SQL Loader 是 Oracle 提供的一个实用程序,用以将外部文件装入 Oracle 数据库。我们认为 SQL Loader 比 imp 更强大、更灵活。SQL Loader 可以筛选进行装入的数据,同时允许装入用于修改数据的 Oracle SQL 函数。除了变量、定长数据和流式数据以外,它还可以装入面向对象的数据、LOB 数据和集合。
装入方式有两种:常规路径和直接路径。从 Oracle 9i 开始,最快的方法就是使用外部表(具有并行性和直接插入)。通过外部表,您可以发出一条 SQL SELECT 语句来装入文件内容。
清单 2 中显示了 Oracle SQL Loader 的语法。注意,您可以通过在命令提示符处发出 sqlldr 命令来获得完整的语法。
清单 2. SQL Loader 的语法
SQLLDR keyword=value [,keyword=value,...] where keywords are userid -- ORACLE username/password control -- Control file name log -- Log file name bad -- Bad file name data -- Data file name discard -- Discard file name discardmax -- Number of discards to allow (Default all) skip -- Number of logical records to skip (Default 0) load -- Number of logical records to load (Default all) errors -- Number of errors to allow (Default 50) |
调用 SQL Loader 的方法只有一种,就是通过使用命令行来进行。为了使用 SQL Loader,您需要一个控制文件。 该控制文件就是 SQL Loader 的“大脑”,提供文件位置、格式、插入目标,等等。控制文件是一种不区分大小写、格式自由的文本文件,其中定义了特殊参数。
下列清单展示了一些使用 SQL Loader 的例子。
- 装入定长记录
发出命令:sqlldr userid=scott/tiger log=course.log control=course.ctl。
清单 3. 定长数据示例,Course.dat
CS3121Theory of Computation I F Vari Hall***** CS3122Theory of Computation II W Norman Bethune CS4101Computer Robotics ****** W Stong College * CS4102Computer Graphics ****** W Earth Science* CS4120Advanced Relational **** F Winter College |
清单 4. Course.ctl
LOAD DATA INFILE 'course.dat' "fix 49" BADFILE 'course.bad' Insert INTO TABLE Course (courseid position (1:6) char, coursetitle position (7:30) char, term position (32:32) char, location position (34:47) char) |
- 装入变长记录
发出命令:sqlldr scott/tiger control=emp.ctl, log=emp.log。
清单 5. 变长数据示例,Emp.dat
1234, "Allan", "IT Specialist", 2345, "April-15-2002", 15000, 3000, 88 2345, Lily Ng, "HR", 7766, Jan-12-2000 , 9000, 2000, 55 3456, "Odelia", "Fun", 8899, " June-11-2001 ", 8000,1000, 77 4567, "Titus", Fun, 6655," Aug-03-2005 ", 5000,200, 76 5678, "Timothy", Sales, 7788, Aug-99-2005", 4000, 2000, 11 |
清单 6. Emp.ctl
LOAD DATA INFILE 'emp.dat' -- emp.dat is the input file BADFILE 'emp.bad' -- bad file DISCARDFILE 'emp.dsc' -- discard file DISCARDMAX 2 -- Max discards allowed before load terminates APPEND INTO TABLE emp FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' -- terminated by comma. Allow double quote (empno, ename, job, mgr, hiredate date(30) "Month-DD-YYYY", sal, comm, deptno) |
- 装入多个表
发出命令:sqlldr scott/tiger control=mul.ctl, log=multables.log。
清单 7. 变长数据示例,EmpOrig.dat
7369 SMITH CLERK 7902 17-DEC-80 800 20 7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 7566 JONES MANAGER 7839 02-APR-81 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 |
清单 8. Mul.ctl
LOAD DATA INFILE emporig.dat BADFILE multables.bad DISCARDFILE multables.dsc APPEND INTO TABLE emp1 when empno<>'7788' FIELDS TERMINATED BY X' 2c ' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS (empno POSITION(1:4) INTEGER EXTERNAL, ename POSITION(7:12) INTEGER EXTERNAL) INTO TABLE emp2 when job = 'CLERK' FIELDS TERMINATED BY X' 2c ' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS (empno POSITION(1:4) INTEGER EXTERNAL, job POSITION(14:22) INTEGER EXTERNAL) |
- 装入分区表
发出命令:sqlldr scott/tiger control=partition.ctl log=partition.log。
清单 9. 示例 Emp_orig.dat
7369, SMITH,CLERK,7902,17-DEC-80,800,20 7499, ALLEN,SALESMAN,7698, 20-FEB-81,1600,300,30 7521, WARD,SALESMAN,7698, 22-FEB-81,1250,500,30 7566, JONES,MANAGER,7839, 02-APR-81,2975,20 7654, MARTIN,SALESMAN,7698, 28-SEP-81,1250,1400,30 |
清单 10. Partition.ctl
LOAD DATA INFILE 'emp_orig.dat' BADFILE 'emp_orig.bad' DISCARDFILE 'emp_orig.dsc' INSERT INTO TABLE empp PARTITION (sal_p2) -- salary with values less than 2000 FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' (empno, ename, job, mgr, hiredate, sal) |
- 装入 LOB 数据
发出命令:sqlldr scott/tiger control=clob.ctl log=clob.log。
清单 11. Mybmp.lst
d:/mybmp/datamovement/impCmdline.png d:/mybmp/datamovement/imphelp.png d:/mybmp/datamovement/impIteractive.png d:/mybmp/datamovement/impParfile.png |
清单 12. Clob.ctl
LOAD DATA INFILE mybmp.lst INTO TABLE MYBMP (filename CHAR(200), bmp LOBFILE(filename) TERMINATED BY EOF) |
- 通过外部表装入
首先使用 create directory load_dir as 'd:/tmp' 创建装入目录,然后运行命令 Sqlplus scott/tiger @external.sql。
清单 13. 示例 Emp_Orig.dat
7369, SMITH,CLERK,7902,17-DEC-80,800,20 7499, ALLEN,SALESMAN,7698, 20-FEB-81,1600,300,30 7521, WARD,SALESMAN,7698, 22-FEB-81,1250,500,30 |
清单 14. External.sql
create table empp (EMPNO NUMBER(4), ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2)) organization external( type oracle_loader default directory load_dir access parameters ( records delimited by newline fields terminated by ',' missing field values are null (empno, ename, job, mgr, hiredate char date_format date mask "dd-mon-yyyy", sal, comm, deptno )) location ('emp_orig.dat')) reject limit 5; |
DB2 Universal Database 提供了相似的实用程序导入数据,即 IMPORT 实用程序。导入和导出支持四种文件格式。所选择的格式通常反映了它来自的源或将要使用的目标工具。通常,诸如 .ixf、.del 或 .asc 等文件扩展名揭示了其内容的格式。例如,employee.ixf 将包含无法编辑的 DB2 UDB 交换格式。导入可以遍历 ixf 格式的类型化表的层次结构。
四种支持的文件格式是:
- 定界 ASCII 文件 - DEL
本格式中,定界符可以是定界的字符、定界的列或定界的行。定界字符格式的默认定界符是双引号("),而定界列的默认定界符则是逗号(,)。注意,默认定界符是可以修改的。对于定界行,UNIX® 的 hex 码是 X' 0A ',而 Windows® 则是 X'0D 0A '。
- 非定界 ASCII 文件 - ASC
非定界 ASCII 文件是指那些带有定长字段的文件。它是由行来定界的连续记录行。该格式通常用于与外部应用程序进行数据交换,而这些外部应用程序带有对准的(aligned)列。
- 集成交换格式文件 - IXF
这是一种在 DB2 UDB 数据库之间进行数据交换的优先选取方法。IXF 文件包含数据库表和索引的结构化描述。注意,该格式通常不能使用文本编辑器进行编辑。
- 工作表格式文件 - WSF
该格式用于 Lotus 1-2-3 和 Symphony 产品之间的数据交换。
为了使用 DB2 import,您必须具有适当的授权和权限。您需要要么具有 sysadm 或 dbadm 权限级,要么具有参与对象上的诸如 CREATETAB、CONTROL、SELECT 和 INSERT 的权限,这取决于所选择的选项。
DB2 UDB import 的语法极其简单。请参考下面的语法。要在线获得语法,就在 DB2 命令行输入 db2 ? import。
清单 15. DB2 UDB import 语法
IMPORT FROM filename OF {IXF | ASC | DEL | WSF} [LOBS FROM lob-path [ {,lob-path} ... ] ] [MODIFIED BY filetype-mod ...] [METHOD {L ( col-start col-end [ {,col-start col-end} ... ] ) [NULL INDICATORS (col-position [ {,col-position} ... ] )] | N ( col-name [ {,col-name} ... ] ) | P ( col-position [ {,col-position} ... ] )}] [ALLOW {NO | WRITE} ACCESS] [COMMITCOUNT {n | AUTOMATIC}] [{RESTARTCOUNT | SKIPCOUNT} n] [ROWCOUNT n] [WARNINGCOUNT n] [NOTIMEOUT] [MESSAGES message-file] {{INSERT | INSERT_UPDATE | REPLACE | REPLACE_CREATE} INTO {table-name [( insert-column , ... )] | hierarchy-description} | CREATE INTO {table-name [( insert-column , ... )] | hierarchy-description {AS ROOT TABLE | UNDER sub-table-name} [IN tablespace-name [INDEX IN tablespace-name] [LONG IN tablespace-name]]} [datalink-specification] filetype-mod: COMPOUND=x, INDEXSCHEMA=schema, FORCEIN, INDEXIXF, IMPLIEDDECIMAL, NOCHECKLENGTHS, NOEOFCHAR, NULLINDCHAR, RECLEN=x, STRIPTBLANKS, STRIPTNULLS, NO_TYPE_ID, NODOUBLEDEL, LOBSINFILE, USEDEFAULTS, CHARDELx, COLDELx, DLDELx, DECPLUSBLANK, DECPTx, DATESISO, DELPRIORITYCHAR, IDENTITYMISSING, IDENTITYIGNORE, GENERATEDMISSING, GENERATEDIGNORE, DATEFORMAT=x, TIMEFORMAT=x, TIMESTAMPFORMAT=x, KEEPBLANKS, CODEPAGE=x, NOROWWARNINGS, NOCHARDEL, USEGRAPHICCODEPAGE hierarchy-description: {ALL TABLES | (sub-table-name [(insert-column, ...)], ...)} [IN] HIERARCHY {STARTING sub-table-name | (sub-table-name, ...)} datalink-specification: ([DL_LINKTYPE URL][{DL_URL_REPLACE_PREFIX prefix | DL_URL_DEFAULT_PREFIX prefix}] [DL_URL_SUFFIX suffix], ...)
|
调用 DB2 UDB import 的方法有三种,如下:
- Control Centre - GUI 方法
Control Centre 是一种易于使用的交互式方法,提供了进行逐步指南的向导。下面有一些使用 Control Centre 和 SAMPLE 数据库执行导入的例子。如果还没有创建 SAMPLE 数据库,就请进入命令行并输入 db2sampl 来创建它。
例 1 - 将逗号定界的文件 employee.del 导入现有的 employee 表。
清单 16 显示了几行 employee.del 文件中的内容。
清单 16. employee.del 的内容示例
"000010","CHRISTINE","I","HAAS","A00","3978",19650101,"PRES ",18,"F",19330824, ... "000020","MICHAEL","L","THOMPSON","B01","3476",19731010,"MANAGER ",18,"M",19480202, ... "000030","SALLY","A","KWAN","C01","4738",19750405,"MANAGER ",20,"F",19410511, ... "000050","JOHN","B","GEYER","E01","6789",19490817,"MANAGER ",16,"M",19250915, ... "000060","IRVING","F","STERN","D11","6423",19730914,"MANAGER ",16,"M",19450707, ... |
本例子中,使用 Control Centre 进行定位。执行 Start -> Programs -> IBM DB2 -> General Administration Tools -> Control Centre。选择 Sample 数据库,单击 Tables,右击 Employee 表并选择 Import。
图 8. 使用 Control Centre 调用表的导入
注意,因为这是定界格式(DEL),选择该选项将允许您选择更多选项,以便更好地控制导入操作。我们不会讨论所有这些选项的细节。本例中,我们指定导入 Employee.del 文件,以及写入的日志文件。还请注意,我们选择 INSERT 方式。您可以选择 INSERT、INSERT_UPDATE 或 REPLACE。对于 INSERT,导入操作只是向现有的表进行追加,而不打乱其余的数据。对于 INSERT_UPDATE,您至少必须有一个主键。新记录将插入,而现有的记录将更新。对于 REPLACE,在插入发生之前,首先将删除表中的数据。
图 9. 导入 - file 选项卡
然后,您将收到一条表示已经成功导入的消息。
例 2 - 本例子中,我们具有一个定界文件,其中忽略最后两列。我们将用 INSERT-REPLACE 选项导入一些列。该文件的格式是星号‘*’定界的。
清单 17 展示了 Employee.del 中的内容示例。
清单 17. Employee 示例数据
"000010"*"CHRISTINE"*"I"*"HAAS"*"A00"*"3978"*19650101*"PRES "*18*"F"*19330824* ... "000020"*"MICHAEL"*"L"*"THOMPSON"*"B01"*"3476"*19731010*"MANAGER "*18*"M"*19480202* ... "000030"*"SALLY"*"A"*"KWAN"*"C01"*"4738"*19750405*"MANAGER "*20*"F"*19410511* ... "000050"*"JOHN"*"B"*"GEYER"*"E01"*"6789"*19490817*"MANAGER "*16*"M"*19250915* ... "000060"*" IRVING "*"F"*"STERN"*"D11"*"6423"*19730914*"MANAGER "*16*"M"*19450707* ... |
在 Control Centre 中,重复例 1 中的相同步骤。但是,您还需要执行一些额外的步骤。选择 DEL 选项按钮。
选择 Column Delimiter(COLDEL)并选择星号‘*’。请注意下拉列表中的其他值。这些是允许的列定界符。其余的采用默认值。单击 OK。
图 10. 选择定界符
现在,进入 column 选项卡,并单击 column 按钮。该步骤是选择要导入或删除的列。
图 11. 选择要包含的列 - 第 1 部分
选择除两列之外的所有列。请注意本例中,最后两列 BONUS 和 SALARY 将被忽略。单击 OK。
图 12. 选择要包含的列 - 第 2 部分
确保您在 File 选项卡中已选择 INSERT_REPLACE 作为导入方式。使用 INSERT_REPLACE 选项的先决条件就是必须存在主键。如果还没有主键,您首先必须发出 SQL 命令来创建主键,例如:alter table employee add constraint empno primary key (pk_empno)。单击 OK。您将看到该导入成功。
- 命令行处理器(Command Line Processor,CLP)- 命令提示符方法
例 1 - 正如上面 GUI 方法中的例 1 一样,我们将一个逗号定界的文件 employee.del 导入现有的 employee 表中。
通过 DB2 CLP,发出下列命令:
清单 18. 使用命令 CLP 进行导入 - 例 1
CONNECT TO SAMPLE; IMPORT FROM "E:/tmp1/employee.del" OF DEL METHOD P (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) MESSAGES "E:/tmp1/employee.log" INSERT INTO ADMINISTRATOR.EMPLOYEE (EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL, SEX, BIRTHDATE, SALARY, BONUS, COMM); CONNECT RESET; |
例 2 - 正如 GUI 方法的示例 2 一样,我们具有一个定界文件,其中忽略最后两列。我们将用 INSERT-REPLACE 选项导入一些列。该文件的格式是星号‘*’定界的。
使用 DB2 CLP,发出下列命令:
清单 19. 使用命令 CLP 进行导入 - 例 2
CONNECT TO SAMPLE; IMPORT FROM "E:/tmp1/employee.del" OF DEL MODIFIED BY COLDEL* METHOD P (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) MESSAGES "E:/tmp1/employee.log" INSERT_UPDATE INTO ADMINISTRATOR.EMPLOYEE (EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL, SEX, BIRTHDATE, SALARY); CONNECT RESET; |
- API - 编码方法
关于 API 指令和示例,请查阅 DB2 Information Center。DB2 附带了 C、C++ 和 COBOL 的代码示例。
除了 DB2 IMPORT,DB2 还提供了一个更快的装入工具 DB2 LOAD,用于将大量数据移至 DB2 UDB 数据库中。不像通过 SQL INSERT 写入数据库的 DB2 IMPORT,DB2 LOAD 直接写入数据库文件。DB2 IMPORT 和 LOAD 都支持用户定义类型(UDT)和 LOB;但是,DB2 LOAD 可以将数据装入分区表中。这两个工具之间的主要区别和使用选择就是性能。DB2 LOAD 比 IMPORT 快得多。
DB2 LOAD 不提供单个记录的日志记录。但是支持重载数据。在装入过程中,DB2 命令 LIST UTILITIES 可以用于监控装入进度。同时,DB2 LOAD 还使用表级锁定,即用户在装入期间无法访问数据。
要使用 DB2 LOAD,您需要 SYSADM、DBADM 或 SYSMAINT 级权限,不然要具有该数据库上的 load 权限和进行 INSERT 和 DELETE 的权限,这取决于所选择的操作。
清单 20 中显示了 DB2 LOAD 的语法。或者,在 DB2 命令提示符处发出 db2 ? import 来查看该语法。
清单 20. DB2 Load 语法
LOAD QUERY TABLE table-name [TO local-message-file] [NOSUMMARY | SUMMARYONLY] [SHOWDELTA] LOAD [CLIENT] FROM file/pipe/dev/cursor_name [ {,file/pipe/dev} ... ] OF {ASC | DEL | IXF | CURSOR} [LOBS FROM lob-path [ {,lob-path} ... ] ] [MODIFIED BY filetype-mod [ {filetype-mod} ... ] ]] [METHOD {L ( col-start col-end [ {,col-start col-end} ... ] ) [NULL INDICATORS (col-position [ {,col-position} ... ] )] | N ( col-name [ {,col-name} ... ] ) | P ( col-position [ {,col-position} ... ] )}] [SAVECOUNT n] [ROWCOUNT n] [WARNINGCOUNT n] [MESSAGES msg-file] [TEMPFILES PATH pathname] {INSERT | REPLACE | RESTART | TERMINATE} INTO table-name [( insert-column [ {,insert-column} ... ] )] [datalink-specification] [FOR EXCEPTION table-name] [STATISTICS {NO | USE PROFILE}] [{COPY {NO | YES { USE TSM [OPEN num-sess SESSIONS] | TO dir/dev [ {,dir/dev} ... ] | LOAD lib-name [OPEN num-sess SESSIONS]}} | NONRECOVERABLE} ] [HOLD QUIESCE] [WITHOUT PROMPTING] [DATA BUFFER buffer-size] [SORT BUFFER buffer-size] [CPU_PARALLELISM n] [DISK_PARALLELISM n] [INDEXING MODE {AUTOSELECT | REBUILD | INCREMENTAL | DEFERRED}] [CHECK PENDING CASCADE {DEFERRED | IMMEDIATE}] [ALLOW NO ACCESS | ALLOW READ ACCESS [USE tblspace-name]] [LOCK WITH FORCE] [[PARTITIONED DB CONFIG] partitioned-db-option [{partitioned-db-option}...]] filetype-mod: NOROWWARNINGS, ANYORDER, BINARYNUMERICS, CODEPAGE=x, DUMPFILE=x, FASTPARSE, NOHEADER, TOTALFREESPACE=x, INDEXFREESPACE=x, PAGEFREESPACE=x, FORCEIN, IMPLIEDDECIMAL, PACKEDDECIMAL, NOCHECKLENGTHS, NOEOFCHAR, NULLINDCHAR=x, RECLEN=x, STRIPTBLANKS, STRIPTNULLS, NODOUBLEDEL, LOBSINFILE, CHARDELx, COLDELx, DLDELx, DECPLUSBLANK, DECPTx, DATESISO, DELPRIORITYCHAR, USEDEFAULTS, DATEFORMAT=x, TIMEFORMAT=x, TIMESTAMPFORMAT=x, ZONEDDECIMAL, KEEPBLANKS, IDENTITYMISSING, IDENTITYIGNORE, IDENTITYOVERRIDE, GENERATEDMISSING, GENERATEDIGNORE, GENERATEDOVERRIDE, USEGRAPHICCODEPAGE partitioned-db-option: HOSTNAME x, FILE_TRANSFER_CMD x, PART_FILE_LOCATION x, OUTPUT_DBPARTNUMS x, PARTITIONING_DBPARTNUMS x, MODE x, MAX_NUM_PART_AGENTS x, OMIT_HEADER, ISOLATE_PART_ERRS x, STATUS_INTERVAL x, PORT_RANGE x, CHECK_TRUNCATION, MAP_FILE_INPUT x, MAP_FILE_OUTPUT x, TRACE x, NEWLINE, DISTFILE x datalink-specification: ([DL_LINKTYPE URL][{DL_URL_REPLACE_PREFIX prefix | DL_URL_DEFAULT_PREFIX prefix}] [DL_URL_SUFFIX suffix], ...) |
DB2 LOAD 操作可以分成四个阶段。这四个阶段是以连续方式发生的:
1. 装入阶段 - 本阶段中,将外部文件中的数据装入表中。对索引进行收集和排序。本阶段中的一件重要事情就是对装入操作进行保存点检查。如果装入失败,就需要该保存点,并且需要执行重载。保存点允许执行这一可重载的功能。本阶段中,无效记录将写入一个消息文件中。
2. 构建阶段 - 本阶段中,将构建索引。如果在该阶段中发生故障,装入操作的重新启动将导致构建阶段从头开始。在该阶段期间,将生成消息。
3. 删除阶段 - 本阶段中,将注意是否违反惟一性和主键约束。违反的行将写入异常表。如果在该阶段中发生故障,装入操作的重新启动将导致删除阶段从头开始。在该阶段期间,将生成消息。
4. 索引复制阶段 - 本阶段中,要将索引从系统临时表空间移至目标表空间。只有在执行装入时为索引的创建指定了系统临时表空间,这一阶段才会发生。在该阶段中,将生成消息。
DB2 LOAD 允许追加或替换数据。在执行装入操作时,将创建一个中间表,以帮助进行装入。可以用 CURSOR 文件类型代替。 同时,还可以选择许多选项,例如:
- WARNINGCOUNT - 指定何时停止装入。当达到 n 条警告时,装入操作将停止。
- CPU_PARALLELISM - 指定 CPU 的并行度。其默认值是一个由 DB2 确定的较明智的值。
- DISK_PARALLELISM - 指定磁盘的并行度。该值确定要派生的线程数目。其默认值是一个由 DB2 确定的较明智的值。
- DATA BUFFER - 指定要使用的 4K 页面的数目。
- TEMPFILES PATH - 指定在装入期间创建中间表时要使用的路径。
- FOR EXCETION - 指定将所有有问题的行写入其中的表。
- DUMPFILE - 指定转储拒绝行错误的文件名。
- NOROWWARNING - 指定对于拒绝行不写入警告。
DB2 LOAD 提供了一些性能调优功能,因为在装入操作期间,可以为创建的页面指定总空间。
- PAGEFREESPACE - 每个数据页留下的空闲百分比。通常,让该值为 DB2 所确定的默认值。
- INDEXFREESPACE - 每个索引页留下的空闲百分比。通常,让该值为 DB2 所确定的默认值。
- TOTALFREESPACE - 追加为空闲空间的表大小百分比。
有关所有其他选项,请查阅 DB2 UDB Data Movement Utilities Guide and Reference。
我们将考查一些关于 DB2 LOAD 如何用于日常操作的例子。与 IMPORT 一样,有三种方式调用 DB2 LOAD,分别是通过使用交互 GUI、命令接口以及通过 API 进行。
- 交互 GUI -
例 1 - 将定界文件装入表。
注意,我们将使用在 IMPORT 例子中所使用的同一 employee.del 作为输入文件,该文件是由逗号定界的。启动 Control Centre。执行 Start -> Programs-> IBM DB2 -> General Administration Tools -> Control Centre。单击 Database,并打开 Sample 数据库。进入 Tables,右击 Employee 表。选择 Load。
图 13. 使用 Control Centre 调用装入表
注意,您可以追加或替换数据。在选择追加时,您还可以选择在表装入期间进行读访问。
图 14. 选择追加或替换
为输入文件名和消息文件输入值。注意,我们没有理会 DEL 选项,因为所使用的默认定界符是逗号,与我们的输入文件相同。如果使用的是另一定界符,就要单击 DEL 按钮,并从 COLDEL 下拉列表中选择需要的定界符。还请注意,数据库可以是本地的,也可以是远程的。
图 15. 指定路径和文件名
本例中,我们将装入除 BONUS 和 COMM 之外的每一列。注意,您也可以指定列行为。
图 16. 选择要包含的列
请注意那些您在 LOAD 期间可以获得的影响性能的选项。我们将采用默认值。
图 17. 性能和统计数据
在该页面上,您有三种选项,即崩溃恢复(crash recovery)、向前(forward)或在装入期间根本不进行恢复。我们将采用默认值。
图 18. 故障和恢复选择
在下列屏幕中采用默认值。这些是您可以使用的高级设置。您可以指定 CPU 并行度、写入的转储文件,等等。
图 19. 选择高级选项
在下列屏幕中采用默认值,并单击 Finish。
图 20. 调度或立即运行
现在,您将看到成功装入的消息。
图 21. 装入成功屏幕
请看一看 Employee.msg。您将看到所有读取、跳过、装入、拒绝、删除和忽略的行。
- 命令 CLP
若使用与检查交互 GUI 方法时相同的例子,要发出下列命令。
清单 21. 使用 CLP 命令的 DB2 装入
CONNECT TO SAMPLE; LOAD FROM "E:/tmp1/employee.del" OF DEL METHOD P (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) MESSAGES "E:/tmp1/employee.msg" INSERT INTO ADMINISTRATOR.EMPLOYEE (EMPNO, FIRSTNME, MIDINIT, LASTNAME, WORKDEPT, PHONENO, HIREDATE, JOB, EDLEVEL, SEX, BIRTHDATE, SALARY) COPY NO INDEXING MODE AUTOSELECT; CONNECT RESET;
|
- API - 编码方法
有关 API 指令和代码示例,请查阅 DB2 UDB Information Center。DB2 附带了 C、C++ 和 COBOL 的代码示例。
下表比较这四种实用程序之间的区别:Oracle imp、Oracle SQL Loader、DB2 UDB IMPORT 和 DB2 UDB LOAD。
表 1. 导入实用程序比较
Oracle Import | Oracle SQL Loader | DB2 Import | DB2 Load | |
通过命令提示符调用 | 通过命令提示符调用 | 通过命令提示符及 API 调用 | 通过命令提示符及 API 调用 | |
只能读取 Oracle Exp 实用程序(请参阅 Exp/Imp 兼容矩阵,metalink note 132904.1)所生成的转储文件 | 从外部文件进行读取 | 从 DEL、ASC、IXF 或 WSF 格式的外部文件进行读取 | 从 DEL、ASC、IXF 或 WSF 格式的外部文件进行读取 | |
用于小型数据库 - 然而,只要满足合适的条件,可移植的表空间可用于大型环境 | 可以处理更大的数据量 | 用于小型数据库 | 用于大型数据库 | |
可以用于通过 INDEXFILE 参数生成 DDL 脚本 | 不会生成 DDL 脚本 | 不会生成 DDL 脚本。DDL 包含在无法编辑的 IXF 格式中 | 不会生成 DDL 脚本 | |
在性能方面不是特别快(不允许 direct=Y) | 在性能方面更快一些 | 在性能方面不是特别快。使用 SQL INSERT | 在性能方面特别快。直接写入数据库 | |
用于包括或排除进行导入的对象的选项较少 | 在进行导入的对象方面稍微灵活一些 | 在进行导入的对象方面十分灵活 | 十分灵活 | |
不可重启 | 可重启 - 可以重载损坏记录 | 可重启 | 可重启 | |
表必须预先存在 | 表必须预先存在 | 表必须预先存在 | 表必须预先存在 | |
从导出转储文件导入表。没有导入多个表的功能 | 并发地装入多个表 | 不支持使用一个通道的从多个源进行的多表导入 | 不支持使用一个通道的从多个源进行的多表导入 | |
可以抑制索引的创建 | 无法抑制索引的创建 | 不存在索引的重新生成。现有索引保持完好 | 不存在索引的重新生成。现有索引保持完好 | |
如果启动 Oracle 8,参数 QUERY 可以用于指定要被导入的行/列 | 可以使用 WHEN 进行列和行的选择。然而,使用 WHEN 时并不支持所有操作符 | 筛选行和列的 where 子句是标准功能 | 筛选行和列的 where 子句是标准功能 | |
COMMIT=Y 在导入每条记录之后进行提交。例如,无法在导入 100 行之后指定提交 | 使用选项 ROWS=n。例如,ROWS=100 在 100 次 SQL Load 之后进行提交 | 使用选项 COMMITCOUNT=5000 在导入 5000 行之后进行提交 | 使用 SAVECOUNT 选项 | |
不会锁定表插入 - 在进行导入时,用户可以进行访问 | 不会锁定表插入 - 在进行导入时,用户可以进行访问 | 支持两种方式 - 离线方式 4(ALLOW NO ACCESS)和在线方式(ALLOW WRITE ACCESS) | 表级锁定。除正进行装入的表之外,用户对于表空间中的所有表具有完全的读、写权限。对于正在装入的表,如果装入是向该表追加数据,那么可以对该表中的现有数据进行读访问 | |
主要用于向后兼容性 | 将持续一段时间,无删除计划 | 将持续一段时间,无删除计划 | 将持续一段时间,无删除计划 | |
到处存在局限性(Gotcha),例如 FULL=Y 需要预防步骤、可移植的表空间,等等 | 在直接路径和并行直接路径装入上存在许多限制 | 限制是无法导入结构类型化列(有关限制列表,请查阅 DB2 Data Movement Util) | 限制在层次表结构的支持上 |
|
不提供本机 API | 不提供本机 API | 提供丰富的 API 集 | 提供丰富的 API 集 |
|
下列基准测试快速查看了在向数据库装入不同的记录数量时,每个工具如何提供较好的性能。下面列出了生成输入文件的代码。
清单 22. 生成 imp/load 文件的 Perl 脚本示例
#!/usr/bin/perl -w my ($sec,$min,$hour,$mday,$mon,$year) = localtime time; $year+=100; # it starts counting at 1900 for ($i=1; $i<100000; $i++) { $datestr = sprintf "%4d%02d%02d", $year, $mon, $mday; print <<ENDLINE; "$i","This is benchmarking test for DB2...", $datestr, "Oracle and DB2 data ...", "Allan W. Tham", "Asean techline..." ENDLINE } |
请查阅 表 2 以查看 DB2 UDB IMPORT 和 LOAD 的性能测试结果。注意,IMPORT 是相当慢的。该测试是使用带有 4GB RAM 的 IBM pSeries P615 2-WAY 1.65GHz 执行的。
表 2. 快速基准测试比较
总行数 | 导入时间(秒) | 装入时间(秒) |
10,000 | 8 | 2 |
50,000 | 39 | 6 |
100,000 | 100 | 11 |
500,000 | 531 | 58 |
1,000,000 | 1109 | 116 |
5,000,000 | 3610 | 454 |
图 22. DB2 Import 和 Load 的快速基准测试
数据移动 - 导出实用程序
- Oracle - exp
- Oracle - 良好的传统 SQL Plus
Oracle exp 实用程序与 Oracle imp 实用程序相对应。即使版本不同,它们也能共存;例如,可以将 Oracle 8i 的导出导入 9i 中。正如前面所提到的,导出以指定顺序将数据库对象写入只有 imp 实用程序可以读取的专用格式中。exp 实用程序用于导出中小型数据库。exp 与参数 DIRECT=Y 一起出现,该参数越过评测缓冲器,从而确保了速度快得多的导出过程。使用 Oracle exp 实用程序有许多好处,例如下面所列的一些:
- 逻辑备份 - exp 实用程序可以用于补充备份和恢复策略。例如,较好的导入将确保恢复意外删除的特定表。
- Reorg - 导入将消除数据库中的碎片。
- 讹误(Corruption)检查 - 导入需要进行全表扫描。任何物理或逻辑讹误都将被检测出来。物理讹误是指已经使用的可能破坏数据的块,而逻辑讹误包含数据字典。
exp 实用程序完全与 imp 实用程序相对。imp 就像吸入,而导出就看作是呼出或吐出部分。调用 exp 实用程序的方法与调用 imp 的相同。导出的语法也十分相似。关键区别就是有了 COMPRESS 和 DIRECT 等参数,而少了 TOUSER 和 FROMUSER 等参数。若要列出完整的列表,就发出命令 exp help=y。请参阅下列语法:
清单 23. Oracle exp 的语法
exp keyword=value [,keyword=value,...] where keywords are USERID username/password BUFFER size of data buffer FILE input files (EXPDAT.DMP) COMPRESS import into one extent (Y) IGNORE ignore create errors (N) GRANTS import grants (Y) INDEXES import indexes (Y) DIRECT direct path (N) ROWS import data rows (Y) CONSISTENT cross-table consistency(N) LOG log file of screen output FULL import entire file (N) OWNER list of owner usernames TABLES list of table names INCTYPE incremental import type RECORDLENGTH length of IO record RECORD track incr. export (Y) TRIGGERS export triggers (Y) STATISTICS analyze objects (ESTIMATE) PARFILE parameter filename CONSTRAINTS import constraints (Y) |
让我们来检查该实用程序所支持的四种导出方式:
- 全导出 - FULL=Y。如果参数 FULL=Y,那么将导出所有对象。发出命令:exp system/password full=y file=scott.dmp log=scott.log direct=y。
- 特定所有者 - OWNER=XYZ。通过该参数,您可以导出属于指定用户的对象。例如,命令 exp system/password owner=scott file=scott.dmp 将导出属于 Scott 的所有对象。
- 表级导出 - TABLES = (*)。通过该参数,指定可以导出的用户模式(schema)所拥有的表。例如,命令:exp scott/tiger file=scott.dmp tables=(emp, dept)。
- 表空间级导出 - Transport_Tablepspace = Y 和 Tablespaces=(A,B,C)。请查阅 场景 小节中的场景 3。
SQL Plus 是从一个或多个表中快速提取数据的方法之一。若要使用 SQL Plus 提取数据,请按照下列步骤进行。
1. SQLplus username/password@dblink
2. 设置格式化参数
3. Spool <output_filename>
4. 运行 SQL 语句以提取数据
5. Spool off
6. 瞧,您已经获得了数据!
DB2 UDB EXPORT 实用程序将数据导出到三种不同的格式:DEL、WSF 和 IXF。DB2 UDB 导出没有什么特别的悬念。下列例子展示了如何使用 DB2 UDB EXPORT。
- 交互 GUI 方法
启动 Control Centre,并右击需要的表以选择 Export 选项。
图 23. 从 DB2 UDB Control Center 调用导出
选择输出格式为 DEL、WSF 或 IXF。还要输入导出文件名和消息文件名。注意,如果您需要导出特定表的列或行的子集,有一个 SQL assist。如果已经知道表的各列,您就可以仅仅在文本框中进行输入,而无需使用 SQL Assist。还有其他选项卡,例如 Columns 和 Schedule。
图 24. 选择导出格式和输出文件名
如果在前面的步骤中选择 DEL,您将无法在 column 选项卡中进行添加。对于 WSF 和 IXF 格式,您可以添加列。这些列指定用于输出文件的名称。本例子中,我们保留默认值。您还可以指定在何处找到 LOB 数据,或者指定找到 LOB 数据的文件名。
图 25. 指定输出文件中的列
最后一个选项卡是 schedule 选项卡。我们选择立即运行。您总是可以调度该任务稍后运行。
图 26. 调度任务
您将看到一条成功消息。
- 命令 CLP 方法
清单 24. 使用命令 CLP DB2 导出示例
CONNECT TO SAMPLE; EXPORT TO "E:/tmp1/employee_1.ixf" OF DEL MESSAGES "E:/tmp1/employee_1.msg" SELECT EMPLOYEE.EMPNO, EMPLOYEE.FIRSTNME, EMPLOYEE.LASTNAME, EMPLOYEE.WORKDEPT, EMPLOYEE.PHONENO FROM ADMINISTRATOR.EMPLOYEE AS EMPLOYEE; CONNECT RESET; |
|
|
Oracle - 数据泵(impdp/expdp)
从 Oracle 10g 开始,Oracle 就提供了一种新的高速数据和元数据泵(pumping)实用程序,名为数据泵(Data Pump)。数据泵将通过在执行数据泵时取得并行流来最大化吞吐量。数据泵(impdp 和 expdp)的新功能就是可以通过定制代码进行调用。使得数据泵(Data Pump)可用的包是 DBMS_DATAPUMP。相较于它的先驱产品,数据泵的关键好处就是装入和卸载的高速度。除了速度(比 imp 快 20-30 倍),其他好处就是可以更好地控制导入和导出的对象。例如,数据泵(Data Pump)可以使用 EXCLUDE 关键字排除一些数据对象,或者使用 EXCLUDE 关键字包含一些数据对象。您还可以使用 CONTENT 关键指定将导出/导入数据还是元数据。通常,APPEND、SKIP、TRUNCATE 和 REPLACE 适用于导入的表。最后但也很重要的一点就是,在装入期间监控诸如完成百分比、工作进度和历史数据等内容。关于完整的参考大全,请查阅 Oracle 10g Utility Guide。
多平台版 IBM DB2 高性能卸载
多平台版 IBM DB2 高性能卸载(IBM DB2 High Performance Unload for Multiplatform)是一个用于 UNIX、Windows 和 Linux® 的高速卸载工具。当数据量十分巨大时,该工具可以用于替代导出。该工具从表空间或备份副本卸载 DB2 表。
IBM DB2 Test Database Generator
IBM DB2 Test Database Generator 是一个用于从主生产中的数据库生成测试数据库的工具。可以从现有的数据库创建一个数据库子集,也可以从头生成一个新的测试数据库。该工具维护数据库的参照完整性。
MTK 版本 1.3 是为从包括 Oracle 8i 和 Oracle 9i 部分支持的多个源数据库管理系统将数据、查询和过程语言迁移到下列目标系统而设计:
- IBM DB2 UDB Universal Database for Workstation 平台,版本 8.1 或更新版本
- IBM DB2 UDB Universal Database for i5/OS,版本 5.2 或更新版本
- IBM DB2 UDB Universal Database for z/OS,版本 8
对于从 Oracle 仓库迁移到 DB2 仓库,MTK 可能十分有用,因为它的功能包括:
- 迁移源可以是数据库数据源或 DDL 脚本。
- 它转换 Transact-SQL 或 PL/SQL 对象定义(包括存储过程、用户定义函数、触发器、包、表、视图、索引和序列)。
- 它具有一个全功能的 GUI 接口(Toolkit),为复杂的数据库转换进一步优化迁移和编制(tailor)选项。
- 它将 Transact-SQL 或 PL/SQL 脚本转换成 DB2 脚本。
- 它生成并运行脚本,以从源卸载数据,然后上传给 DB2。
developerWorks DB2 库包含了许多与 DB2 迁移主题有关的参考资料,特别是关于 MTK 的教程和技术文章:
MTK 在 AIX®、Linux、Sun Solaris 和 Windows 上运行。惟一可用的语言就是英语。可以从 IBM DB2 Migration Toolkit 站点完整下载 MTK。
本小节将考查一些场景,其中展示了在 Oracle 和 DB2 UDB 世界中是如何完成这些事情的。注意,这里所呈现的解决方案并没有穷举所有可能。
- 场景 1 - 数据文件移动
在 Oracle 中,为了在表空间中重新定位(relocate)数据文件(不关闭数据库),需要执行下列步骤:
- Alter tablespace USERS read only - 使得该表空间为只读的。
- 使用 OS 级复制将数据文件复制到新的位置。
- Alter tablespace USERS offline - 一旦完成了复制,就使表空间 USERS 离线。
- Alter database rename '/oldpath/old_datafile1.dbf' to '/newpath/new_datafile1.dbf' - 使用旧的和新的全路经一个接一个地对数据文件进行重新命名。
- Alter tablespace USERS online - 再次恢复该表空间的在线状态。
- Alter tablespace USERS read write - 解除该表空间的只读模式。
在 DB2 UDB 中,只要发出带有正确参数的命令 db2relocatedb。例如,db2relocatedb -f configFilename,其中 configFilename 就是 清单 25 中所看的:
清单 25. db2relocatedb 的示例配置文件
DB_NAME=oldName,newName DB_PATH=oldPath,newPath INSTANCE=oldInst,newInst NODENUM=nodeNumber LOG_DIR=oldDirPath,newDirPath CONT_PATH=oldContPath1,newContPath1 CONT_PATH=oldContPath2,newContPath2 |
注意,不像 Oracle,DB2 允许在一条命令中重新命名数据库名、路径、实例名和日志目录,只要是在配置文件中指定的即可。
- 场景 2 - 从同一 OS 和 DB 版本迁移数据库
在 Oracle 中,如果您出于某种原因需要从同一操作系统中的同一数据库版本迁移数据库(例如,从 Windows 2000 中的 Oracle 9i(发布 2)迁移至另一台机器上,其中也是 Windows 2000 环境并带有相同的 Oracle 版本),实际上就有一种快速的方法,而无需使用 Oracle imp/exp。在该情况下,您使用 create controlfile 选项。让我们假设旧的数据库名为‘AWT’,而新的为‘AWT1’。注意,这些步骤与控制文件完全丢失的情况相似。
- Alter database backup control file to trace - 备份控制文件。
- Shutdown immediate - 在源机器上关闭数据库清理(clean)。
- 复制转储文件 init.ora,并改写至目标机器。
- 编辑追踪文件,以便它读取第一行中的‘Create controlfile reuse set database "AWT1" resetlogs’。在新环境中,还要为数据文件和日志文件编辑任何结构化的修改。保存该文件,例如保存到 createControlFile.sql。
- 编辑 init.ora 文件以便也反映新的环境。那将包含 SID,其中包括修改的路径。
- 在新的机器中启动 mount 并运行 createControlFile.sql。
- Alter database open resetlogs - 您只能选择重新设置日志。
- 您可能还需要重新命名全局名。
本例中,DB2 UDB 整个就要更加简单。DB2 UDB 提供了 BACKUP 和 RESTORE 命令。BACKUP 命令将数据库备份至用户所指定的目录中。该备份可以使用 OS 级复制进行复制。restore 将通过在新环境中覆盖同一数据库或恢复到动态指定的新数据库名来进行恢复。假定‘SAMPLE’是旧环境中的数据库,而‘SAMPLE1’是新环境中的目标数据库。您可以从命令 CLP 执行下列步骤。注意,下面的备份是一种离线备份方法。
- 使用命令 db2 backup database sample to E:/SampleBKUP 进行备份。
- 使用 OS 进行复制,将整个文件夹、SampleBKUP 复制到新环境中。
- 使用命令 db2 restore database sample from E:/YYY/SampleBKUP (恢复到现有的数据库中)或
- db2 restore database sample from E:/YYY/SampleBKUP into SAMPLE1(恢复到新的数据库中)进行恢复。
- 场景 3 - 在同一 OS 中将数据库从低版本迁移至高版本(不同机器中的 Oracle 8.1.7 到 9iR2)
最佳方法就是通过使用导入和导出实用程序,使用所支持的迁移。在进行尝试之前,请注意,低版本到高版本的迁移是所支持的一种。关于兼容性,请查阅 Oracle Metalink Note Id 132904.1。本例中,您实际上具有下列选择:
- 全数据库导出
- 表空间级导出
- 模式级导出
- 表级导出
我们将考虑使用表空间级的可移植导出/导入。假定具有一个表空间 USERS,且要移植模式 LILY。
在 Oracle 8.1.7 (源)上执行下列步骤:
- Alter tablespace USERS read only
- exp /"sys/password as sysdba/" file=trans817.dmp tablespaces=users transport_tablespace=y
- 将属于 USERS 表空间和 trans817.dmp 的数据文件经磁带复制到 Oracle 9iR2 所在的新机器上
- 删除包含内容的表空间 users(如果 USERS 表空间已经存在)
- imp /"sys/password as sysdba/" file=trans817.dmp transport_tablespace=y datafiles=users01.dbf
注意,为了使用可移植的表空间,Oracle 版本必须是 8i 或 9i。您可以移植到更高的版本,但不可以是更低版本。请查阅 Metalink note 77523.1 和 291024.1。同时,在使用可移植的表空间进行导出/导入之前,必须遵守下列限制:
- 对于 Oracle 8i 和 9i 的操作需要是相同的。对于 Oracle 10g ,可移植的表空间可以跨多个平台使用。同样,Oracle 7 中不支持可移植的表空间。
- 源数据库和目标数据库的数据块大小和 charset 相同。
- 目标不应具有预先存在的表空间名。
- 不支持快照/复制、基于函数的索引、区域引用(Scoped REF)、域索引,等等。
- 表空间必须是独立的(self contained)。
对于 DB2 UDB,因为源数据库和目标数据库的操作系统相同,所以本场景与上面第一个场景 2 相同。简单地将备份文件夹复制到新机器上,并恢复它。
- 场景 4 - 将数据库从相同的 DB 版本迁移到不同的 OS(例如,从 Windows 2000 SP4 到 AIX 5.2 ML4)
本场景中,您在 Oracle 中除了导出和导入,别无选择。您可以执行全数据库导出、模式级或表级导出。注意,为了使可移植的表空间跨不同的平台工作,您至少需要有 Oracle 10g 。按照下列步骤执行全导出和导入。请确保启用了角色 IMP_FULL_DATABASE。若要执行全数据导出和导入,请执行下列步骤。
- imp system/manager full=y constraints=n indexes=n file=full817.dmp log=full817_1.dmp
- imp system/manager full=y constraints=y indexes=y rows=n ignore=y file=full817.dmp log=full817_2.log
注意,您将看到整批“objects already exist”错误,因为该系统和 sys 对象已经存在。
在 DB2 UDB 中,有两种方法完成该任务。
- 使用备份和恢复 - 在 AIX 和 Solaris 和 HPUX 之间备份/恢复工作。
- 使用 db2move 实用程序 - 将数据库移入/移出包括 Linux、Unix、Windows(LUW)在内的不同平台和驻留在主机系统中的数据库。
若要使用 Backup & Restore 选项,请执行下列步骤。
- 从源机器(例如 AIX)发出备份命令:db2 'backup database sample to "/home/db2inst1/sample"'。
- 将带有长名的文件 FTP 至目标(例如 Solaris)。
- 发出恢复命令:db2 'restore database sample from "/home/db2inst1"'。
当使用 DB2move 时,它首先将数据导出至 ixf 格式中。 执行下列步骤:
- 在 Windows 的 DB2 UDB 8.2 中,通过发出命令 db2move sample export -tc administrator 导出数据。
- FTP 至 AIX 机器。
- 预先创建表以驻留在理想的表空间中。注意,虽然 db2move 为您创建该表,但它可能不在理想的表空间中。使用命令 db2look -d sample -u administrator -e -m -o sample.sql 为这些表找到表空间。
- 在 AIX 中发出命令 db2move sample load -lo replace。如果您的表没有预先创建,那么将获得 SQL3304N The table does not exist 消息。(请查阅 DB2 UDB Information Centre,因为 db2move 提供了比这里所呈现的更多的选项)。
- 场景 5 - 在不同的操作系统之间将数据库从低版本迁移至高版本
在 Oracle 中,如果您的数据库是 8i 或 9i,那么可移植的表空间就无法用于跨平台。如果是 8i 或 9i,惟一的选择就是 imp/exp。然而,如果使用 10g ,那么完成该任务的最佳方法就是使用可移植的表空间。
在 DB2 UDB 中,这与场景 4 相同。您可以选择使用 DB2 Backup 和 Restore 或 db2move。
虽然在 Oracle 和 DB2 UDB 中有许多完成数据移动的方法,但是通常决定一种方法胜于其他的因素就是经济因素。DBA 的工作通常必须面对当前环境的约束。本文中,我们查看了一些在 Oracle 和 DB2 世界中可以完成数据移动的方法。此外,我们介绍了一些管理 DB2 数据库的工具,例如 IBM DB2 Test Database Generator 和高速卸载工具 IBM DB2 High Performance Unload for Multiplatform。对于需要从 Oracle 迁移到 DB2 UDB 的用户,IBM MTK 是一种补充工具,用于加速迁移过程。
作者特别感谢 Amyris Rada,他是 IBM 位于加拿大多伦多的 i2 Partner Integration Center 的团队领导。Amryis 为本文的 IBM Migration Toolkit(MTK)部分提供了贡献。
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
- 在 http://tahiti.oracle.com 上可以找到 Oracle 文档。
- 在 Oracle Metalink 中,可以获得良好的信息源。
- DB2 Information Center 是一个很好的信息源,涉及 DB2 的各个方面。
- 您可以在这里获得 DB2 UDB 产品手册的副本:DB2 UDB 8.2 Manuals。
- 有关用于快速填充应用程序和测试环境的这一工具的更新信息,请访问 IBM DB2 Test Database Generator 页面。