【IT168 技术】本文主要讲解从DB2 v9.7 PHSDB库迁移到K-DB11G非常好的实践,迁移数据库名为PHSDB,数据库架构为单机。首先在目标主机上安装K-DB11g软件,并创建PHSDB库,具体安装过程请参考管理手册。本次迁移范围包括数据库对象和数据两部分,以下分两部分别进行介绍。
注意:保证源库和目标数据库字符集一致。整个迁移流程如下:
第一部分介绍数据库对象迁移
实际迁移中需要把DB2的一个schema分别对应K-DB一个用户,schema和用户名称建议一致。首先进行DB2数据库对象种类分析、数据类型分析、数据量分析等,通过Sql develper工具连接到 DB2 数据库进行数据对象分析,捕获源数据库对象,并在制定目录中自动生成K-DB支持的建用户、表、主键、索引、约束外键、列默认值和标识列语句的脚本;如果存在其他对象类型,需要人工参与修改。经分析源PHSDB库包括表、主键、索引、外键约束、序列、视图、函数、列默认值和标识列对象,脚本中把DB2 schema PHS映射成K-DB PHS用户,所有对象通过PHS用户创建,并授予K-DB PHS用户CREATE SESSION, RESOURCE, CREATE VIEW, CREATE MATERIALIZED VIEW, CREATE SYNONYM系统权限,表空间使用user表空间,临时表空间使用temp。
DB2和K-DB数据类型转换格式如下:
注意:IBM DB2完整性约束语句支持ON DELETE and ON UPDATE写法,K-DB仅支持ON DELETE完整性约束,工具已经完成自动装换。
具体DB2和K-DB约束对比如下:
在本次迁移过程中,所有外键约束语法只包括ON UPDATE RESTRICT,ON DELETE RESTRICT约束,通过工具已经自动转换全部符合K-DB约束语法。例如:
DB2语句:
ALTER TABLE "PHS"."P_PACKAGE_GROUP"
ADD CONSTRAINT "FK2_P_PACKAGE_GROUP" FOREIGN KEY
(
"PACKAGEID"
)
REFERENCES "PHS"."P_PACKAGE"
(
"PACKAGEID"
)
ON UPDATE RESTRICT
ON DELETE RESTRICT
;
转换后K-DB语句:
ALTER TABLE P_PACKAGE_GROUP
ADD CONSTRAINT P_PG_PACK_FK FOREIGN KEY
(
PACKAGEID
)
REFERENCES P_PACKAGE (
PACKAGEID
)
ENABLE
;
本例中列默认值转换语法如下,DB2语句:
ALTER TABLE "PHS"."P_INSTANCE" ALTER COLUMN "PERSONID" SET WITH DEFAULT -1 ; ALTER TABLE "PHS"."CHRONIC_TEMPLATE" ALTER COLUMN "MEDEVENT" SET WITH DEFAULT 8 ;
转换后K-DB语句:
ALTER TABLE "PHS"."CHRONIC_TEMPLATE" MODIFY "MEDEVENT" DEFAULT 8 ; ALTER TABLE "PHS"."P_INSTANCE" MODIFY "PERSONID" DEFAULT -1 ;
在DB2中存在自动递增标识列,K-DB使用序列和触发器模仿DB2标识列,针对DB2的每个带有标识列创建语句分别增加相对应创建序列和触发器语句。
源PHSDB数据库带有自增标识列语法如下:
CREATE TABLE "PHS"."BATCH_TASK_RECORDS"
(
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 41, INCREMENT BY 1, CACHE 20),
"STATUS" INTEGER ,
"JOBSTARTTIME" TIMESTAMP ,
"JOBENDTIME" TIMESTAMP ,
"SDATE" TIMESTAMP ,
"EDATE" TIMESTAMP ,
"TYPE" VARCHAR(50)
)
;
K-DB转换后使用序列和触发器解决提供解决方案:
CREATE TABLE BATCH_TASK_RECORDS (
ID NUMBER(10,0) NOT NULL,
STATUS NUMBER(10,0),
JOBSTARTTIME TIMESTAMP(9),
JOBENDTIME TIMESTAMP(9),
SDATE TIMESTAMP(9),
EDATE TIMESTAMP(9),
TYPE VARCHAR2(50 CHAR)
);
CREATE SEQUENCE BATCH_TASK_RECORDS_ID_SEQ
MINVALUE 1 MAXVALUE 999999999999999999999999 INCREMENT BY 1 NOCYCLE ;
CREATE OR REPLACE TRIGGER BATCH_TASK_RECORDS_ID_TRG BEFORE INSERT ON BATCH_TASK_RECORDS
FOR EACH ROW
DECLARE
v_newVal NUMBER(12) := 0;
v_incval NUMBER(12) := 0;
BEGIN
IF INSERTING AND :new.ID IS NULL THEN
SELECT BATCH_TASK_RECORDS_ID_SEQ.NEXTVAL INTO v_newVal FROM DUAL;
-- If this is the first time this table have been inserted into (sequence == 1)
IF v_newVal = 1 THEN
--get the max indentity value from the table
SELECT NVL(max(ID),0) INTO v_newVal FROM BATCH_TASK_RECORDS;
v_newVal := v_newVal + 1;
--set the sequence to that value
LOOP
EXIT WHEN v_incval>=v_newVal;
SELECT BATCH_TASK_RECORDS_ID_SEQ.nextval INTO v_incval FROM dual;
END LOOP;
END IF;
--used to help get last identity value
db2_utilities.identity := v_newVal;
-- assign the value from the sequence to emulate the identity column
:new.ID := v_newVal;
END IF;
END;
DB2 PHSDB库中包括序列、视图、函数对象,无法通过Sql developer完成自动转换。利用IBM IDMT工具首先进行对象脚本卸载,脚本生成在用户指定目录结构中,由于DB2和K-DB在rownum使用、取系统日期、空值转换、数据类型函数、数值转换函数和子查询等语法使用上存在差异,需要人工把视图和函数改成K-DB支持的语法,具体更改过程参照K-DB语法解释。
序列创建语句对比例子如下:
最后通过在K-DB数据库依次运行建表和修改后数据对象创建脚本,完成整个PHSDB数据对象的迁移。
第二部分进行数据迁移
数据迁移脚本主要包括Db2_data.sh卸载数据脚本和Import_kdb.sh加载数据脚本。Db2_data.sh进行DB2数据卸载,Import_kdb.sh完成K-DB数据导入操作。
Db2_data.sh卸载脚本语句如下:
db2 export to data/PHS_APPROLE.TXT of DEL modified by coldel"#" datesiso nochardel "select \"ID\",'<EOFD>',\"ROLENAME\",'<EOFD>',\"DESCRIPTION\",'<EOFD>', '<EORD>' from PHS.\"APPROLE\""
db2 export to data/PHS_UTS_CHRONIC_MED.TXT of DEL modified by coldel"#" datesiso nochardel "select \"MEDID\",'<EOFD>',\"MEDICATION\",'<EOFD>',\"SPECIFICATION\",'<EOFD>',\"SPELLING\",
'<EOFD>',\"MEDUNIT\",'<EOFD>', '<EORD>' from PHS.\"UTS_CHRONIC_MED\""
……
Import_kdb.sh导入数据脚本语句如下:
tbloader userid=$username/$password@$tnsname control=control/PHS.APPROLE.ctl log=log/PHS.APPROLE.log
tbloader userid=$username/$password@$tnsname control=control/PHS.UTS_CHRONIC_MED.ctl log=log/PHS.UTS_CHRONIC_MED.log tbloader userid=$username/$password@$tnsname control=control/PHS.PES_UPLOAD_JOB.ctl log=log/PHS.PES_UPLOAD_JOB.log
tbloader userid=$username/$password@$tnsname control=control/PHS.P_INST_DISEASE.ctl
利用batch_ctl.sh脚本批量生成tbloader使用的控制文件,该脚本是通过抓取目标数据库已经生成的表结构,利用shell语句封装成控制文件。
tbloader控制文件内容如下:
# load data by tbloader
load data
infile 'PHS.APPROLE.dat'
logfile 'log/PHS.APPROLE.log'
badfile 'log/PHS.APPROLE.bad'
append
into table PHS.APPROLE
fields terminated by '#<EOFD>#'
LINES TERMINATED BY '<EORD>\n'
(
ID ,
ROLENAME ,
DESCRIPTION )
最后运行Import_kdb.sh脚本进行数据加载,确认脚本执行完成后,使用gather_data.sh脚本进行数据校验分析,确认迁移数据成功,至此本次迁移完成。
注意:由于约束会造成部分数据导入不成功,我们在执行数据加载前分别执行Pro_load.sh和Modify_null.sh两个脚本,把外键约束禁用和冗许字段为空;执行Import_data.sh迁移数据后,再执行Post_load.sh和Modify_not_null.sh启用约束,脚本分别放到Import_kdb.sh脚本初始和结尾中。