Linux 下的 DB2数据库的迁移
文章出自:http://macrozeng.itpub.net/post/71/58248
前言:
DB2 Universal Database™(DB2 UDB) 有一对非常有用的工具,可以帮助您实现这种跨平台的备份与恢复功能。 db2move 工具利用了 DB2 的数据移动工具(export 和 import 或 load)来移动数据库表。然而,由于数据库的内容远远不止于用户表,因此您需要使用其他方法在不同的数据库之间迁移其他数据库对象,例如约束、触发器、索引、序列、表空间、缓冲池等。这就是 db2look工具出现的原因。使用这个工具,您可以在源数据库中捕获到定义这些对象使用的数据定义语言(DDL),并在目标数据库中使用这些数据定义语言重新创建这些对象。
1、 环境说明:
迁移的DB2 数据库的名字叫 sample , SCHEMA也是oatest ,用户名是 oatest
2、 导出步骤:
1) 建立新目录,如果是在 linux 下要注意目录的权限问题,目录应该可以被 db2inst1 用户写访问
[db2inst1@devsvr2 db2inst1]$ pwd /home/db2inst1 [db2inst1@devsvr2 db2inst1]$ mkdir oatest0303 [db2inst1@devsvr2 db2inst1]$ ls db2inst1 db2test Desktop oatest0303 sqllib |
2) 进入该目录
[db2inst1@devsvr2 db2inst1]$ cd oatest0303/ [db2inst1@devsvr2 oatest0303]$ |
3) 用数据库抽取工具 db2look 导出数据库结构
主要命令
db2look -d sample -e -z oatest -l -o oatest.sql
[db2inst1@devsvr2 oatest0303]$ db2look -d sample -e -z oatest -l -o oatest.sql -- 未指定用户标识,db2look 试图使用环境变量 USER -- USER 是: DB2INST1 -- 指定的模式为: OATEST -- 创建表的 DDL
-- 联合部分的模式名被忽略 -- 输出被发送到文件: oatest.sql |
脚本中包括建立 bufferpool 以及tablespace的 DDL 语句
4) 用 db2move 工具导出数据库数据
主要命令
db2move sample export
[db2inst1@devsvr2 oatest0303]$ db2move sample export
***** DB2MOVE *****
Action: EXPORT
Start time: Sun Mar 5 11:00:52 2006
Connecting to database SAMPLE ... successful! Server: DB2 Common Server V8.2.0
EXPORT: 0 rows from table "OATEST "."ATTACHFILE" EXPORT: 0 rows from table "OATEST "."BASE" …… |
5) 打包压缩该目录 oatest0303/
主要命令:
tar zcvf oatest0303.tar.gz oatest0303/
[db2inst1@devsvr2 oatest0303]$ cd .. [db2inst1@devsvr2 db2inst1]$ tar zcvf oatest0303.tar.gz oatest0303/
oatest0303/ oatest0303/oatest.sql oatest0303/EXPORT.out oatest0303/db2move.lst oatest0303/tab1.msg oatest0303/tab1.ixf …… |
3、 导入步骤
1) 解压
主要命令:
tar zxfv oatest0303.tar.gz
[db2inst1@devsvr2 db2inst1]$ tar zxfv oatest0303.tar.gz oatest0303/ oatest0303/oatest.sql oatest0303/EXPORT.out oatest0303/db2move.lst …… |
2) 建立新数据库 db2 create db sample
主要命令:
db2 create db sample
[db2inst1@devsvr2 db2inst1]$ db2 create db sample DB20000I CREATE DATABASE 命令成功完成。 |
3) 执行 oatest.sql 脚本建立数据库
主要命令:
db2 -tvf oatest.sql
[db2inst1@devsvr2 db2inst1]$ cd oatest0303 [db2inst1@devsvr2 oatest0303]$ db2 -tvf oatest.sql …… |
4) 执行 db2move 导入数据
主要命令:
db2move sample load
[db2inst1@devsvr2 oatest0303]$ db2move sample load …… * LOAD: table "OATEST "."UM_USER" -Rows read: 1529 -Loaded: 1529 -Rejected: 0 -Deleted: 0 -Committed: 1529
Disconnecting from database ... successful!
End time: Sun Mar 5 10:24:22 2006 |
5) 检查一致性
主要命令:
db2 set integrity for oatest.UM_USER immediate checked
[db2inst1@devsvr2 oatest0303]$ db2 connect to sample
数据库连接信息
数据库服务器 = DB2/LINUX 8.2.0 SQL 授权标识 = DB2INST1 本地数据库别名 = SAMPLE
[db2inst1@devsvr2 oatest0303]$ db2 "select count(*) from
1 ----------- SQL0668N 由于表 "OATEST.UM_USER" 上的原因码 "1",所以不允许操作。 SQLSTATE=57016 [db2inst1@devsvr2 oatest0303]$ db2 set integrity for oatest.UM_USER DB20000I SQL 命令成功完成。 [db2inst1@devsvr2 oatest0303]$ db2 "select count(*) from
1 ----------- 1529
1 条记录已选择。
|
利用 sql 语句得到要检查的表的执行语句
主要命令:
db2 "select 'db2 set integrity for oatest.'||TABNAME||' immediate checked' from syscat.tables where TABSCHEMA='OATEST' and STATUS='C'"
[db2inst1@devsvr2 oatest0303]$ db2 "select 'db2 set 1 ----------------------------------------------------------------- …… db2 set integrity for oatest.UM_USER immediate checked
81 条记录已选择。 |
执行这 81 条语句,语句有可能报错
主要命令:
db2 set integrity for oatest. CAL_AUTH immediate checked
[db2inst1@devsvr2 oatest0303]$ db2 set integrity for oatest.CAL_AUTH immediate checked DB20000I SQL 命令成功完成。 [db2inst1@devsvr2 oatest0303]$ db2 set integrity for oatest.UM_USER immediate checked DB20000I SQL 命令成功完成。 ………… |
如果报错,再反复执行这些语句直到下面的语句结果返回 0 条记录
[db2inst1@devsvr2 oatest0303]$ db2 "select 'db2 set integrity
1 --------------------------------------------------------------- 0 条记录已选择。 |
6) 在操作系统中建立用户
[root@devsvr2 root]# useradd oatest [root@devsvr2 root]# passwd oatest Changing password for user oatest. New password: BAD PASSWORD: it is too short Retype new password: passwd: all authentication tokens updated successfully. |
7) 给 oatest 用户授权
主要命令:
db2 GRANT DBADM,CREATETAB,BINDADD,CONNECT,CREATE_NOT_FENCED_ROUTINE,IMPLICIT_SCHEMA,LOAD,CREATE_EXTERNAL_ROUTINE,QUIESCE_CONNECT ON DATABASE TO USER OATEST
db2 GRANT CREATEIN,DROPIN,ALTERIN ON SCHEMA OATEST TO USER OATEST
[db2inst1@devsvr2 db2inst1]$ db2 connect to sample
数据库连接信息
数据库服务器 = DB2/LINUX 8.2.0 SQL 授权标识 = DB2INST1 本地数据库别名 = SAMPLE
[db2inst1@devsvr2 db2inst1]$ db2 GRANT DBADM,CREATETAB,BINDADD,CONNECT,CREATE_NOT_FENCED_ROUTINE, DB20000I SQL 命令成功完成。 [db2inst1@devsvr2 db2inst1]$ db2 GRANT CREATEIN,DROPIN,ALTERIN ON SCHEMA OATEST TO USER OATEST DB20000I SQL 命令成功完成。 [db2inst1@devsvr2 db2inst1]$ db2 connect to sample user oatest using oatest
数据库连接信息
数据库服务器 = DB2/LINUX 8.2.0 SQL 授权标识 =OATSET 本地数据库别名 = SAMPLE
[db2inst1@devsvr2 db2inst1]$ db2 "select count(*) from um_user"
1 ----------- 1529
1 条记录已选择。 |
4、 重要说明
1)在 db2 中的 bufferpool 是和内存有关系的,所以你应该根据你的机器内存情况来建立 bufferpool
2) tablespace 的路径也是和你的应用有关,如果是双机环境应该把表空间建立在共享存储中,你可以根据实际情况来修改上文所说到的 oatest.sql 中的建立 bufferpool 以及 tablespace 的语句。
在检查一致性的时候,如果遇到某张表由于外键的关系无法通过一致性检查,可以采用下面的步骤来解决
1、删除外键
ALTER TABLE MV_DATA_HISTORY DROP CONSTRAINT FK_MV_DATA___ADV24
2、检查一致性
set integrity for MV_DATA_HISTORY immediate checked
3、重新创建 NOT ENFORCED 外键
ALTER TABLE MV_DATA_HISTORY
ADD CONSTRAINT "FK_MV_DATA___ADV24" FOREIGN KEY
("FORM_DATA_INST_ID")
REFERENCES MV_FORMSET_INST
("FORMSET_INST_ID")
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT ENFORCED
如果在导出的时候出现类似下面的提示
SQL3132W The character data in column "PRIORITY" will be truncated to size "64".
是因为 codepage 的问题,通过 db2set 设置 db2codepage 和数据库一致,然后重启 instance 就可以了导出了
如果 db2move dbname load 需要执行第二次的时候,可以使用 db2move dbname load -lo REPLACE 来replace 上次导入的记录,否则有些没有主键的表可能会出现重复记录
load 的时候可能会由于 log 满的问题,造成记录数过大的时候无法导入,这时这张表的访问可能如下:
D:Work>db2 select * from sales
SQL0668N Operation not allowed for reason code "3" on table "YASIR.SALES".
SQLSTATE=57016
可使用类似
下面的命令把日志文件的大小和日志文件的数量扩充,如下:
db2 update db cfg for DATABASE using LOGFILSIZ 7900
db2 update db cfg for DATABASE using LOGPRIMARY 30
db2 update db cfg for DATABASE using LOGSECOND 20
然后再用类似
DB2 "LOAD FROM EXPORTED_DATA.IXF OF IXF SAVECOUNT 20000 RESTART INTO YASIR.SALES"
重新导入该表