王飞鹏
作者王飞鹏·2013-10-20 09:11
信息分析/架构师·IBM

某高铁行业Oracle/SQL Server到DB2迁移实战案例

字数 5079阅读 21678评论 11赞 1

   当前,在数据库项目中,风险最高的要数异构数据库迁移了,毕竟这涉及到异构数据库本身存在较大区别,例如SQL语句、锁机制都存在很大差异;异构数据库在设计和开发上区别更大,例如分区技术的不同,例如编程接口的不同;异构数据库在运维上区别也很大。因此,有人说,异构数据库迁移不仅仅是数据库的迁移,也是开发人员和运维人员在技术上的一次重大转型。

   作为国内最专注数据库迁移和性能优化服务的尚端科技暨宝华数据中心(www.baochina.net),在2013年9月15日,接到一个高铁行业客户的需求,项目工期很紧张,实施难度大,需要以最高的效率实现从Oracle到DB2迁移。收到这个请求后,宝华数据咨询中心第一时间派出资深迁移工程师对Oracle数据库进行了评估,并给出了迁移方案和计划,专业的服务和丰富的实战经验获得了客户的高度认可。于是,在接下来的4周内,通过到客户现场驻场的方式,按照舞动DB2系列《从Oracle到DB2开发-从容转身》书中有关方法和最佳实践,在一个月以内成功实施了数据库迁移项目,使得客户的选型风险降到最低,获得了客户和开发商的好评。为了交流技术,下面分享出来,供大家学习。

 

1.  概述

1.1 系统现状

该高铁运营商使用的MTR系统采用了C/S的结构,应用开发使用C语言开发,后台采用Oracle数据库,对数据库的访问使用OCI接口,并且自己封装了DAO层。典型用例中,同时在线用户在5000左右,数据库操作是混合负载,包括批量事务事务处理和报表分析应用。最终部署平台是Power 770双机。

1.2 迁移现状

自从迁移项目组进驻后,得到了各位领导和员工的大力支持,克服了很多困难,首先分别安装了三套DB2环境,分别基于AIXLinuxSolaris。主要迁移了下面的对象,包括表、视图、触发器、自定义函数,序列等数据库对象,其中整个系统中难度最大是共有80000多行PL/SQL代码。

数据库对象

数量(单位:个)

424

索引

232

视图

64

触发器

28

序列

68

约束

391

报表模块:包头

共57个,5000行代码

报表模块:包体

共57个,80000行代码

1.3 迁移难点

经过和相关人员沟通发现,该迁移项目的技术难点包括下述内容:

内容

描述

解决办法

Oracle数据库内置包,主要是DBMS_JOB、UTIL_FILE和DBMS_APPLICATION_INFO迁移;应用中使用到了Oracle Session;应用中使用了Oracle 系统表。

首先,应用中使用到了Oracle的这三个内置包;另外也使用到了Oracle Session来开发应用;最后,应用会读取Oracle系统表中的信息。

DB2 10.5 提供了相关实现,但还需要实际检验。

方法一:通过DB2相关技术方法绕开。

方法二:寻求IBM原厂支持。

和Oracle不兼容点迁移

主要包括PL/SQL,自定义函数,触发器等

迁移团队已经积累了丰富的这方面经验,可以通过相关技术手段解决。

Oracle XMLDB

使用XMLDB用来解析XML格式发过来的报文。

方法一:使用DB2 pureXML技术;

方法二:使用CLOB进行模拟,随后用单独的解析器解释。

Oracle OCI应用

代码量比较大,主要集中在DAO这一层。

方法一:使用DB2 CLI接口替换

方法二:开发一个包装器,用以封装对DB2数据库的访问。

2.  迁移

迁移过程包括下面的一些步骤:

2.1 数据库对象迁移

    数据库对象的迁移,主要包括表,视图,索引,存储过程、触发器和用户自定义函数的迁移工作。

2.2 数据迁移

     数据的迁移通过DB2 DMT或者Datastage来完成。这些工具都提供了数据的快速卸载和装载的能力,能够快速高效的完成数据迁移的工作。

2.3 应用迁移

    应用迁移主要是MTR系统的迁移,包括CLI/DAO层的迁移,包括所有技术难点的解决,例如应用中对Oracle内置包使用的修改等。

2.4 测试

l 功能性测试:运行测试用例,来验证。

l 数据验证测试:通过对比Oracle中源数据和DB2中迁移过来的新数据来验证。

l 性能测试:同一种硬件环境下,分别对比用例在Oracle和DB2运行下的性能。

 

3.  主要问题和解决办法

目前在从Oracle到DB2迁移中,没有那么容易,经常出现一些莫名其妙地问题,下面仅举13个例子,这些都是在我们迁移中遇到的:

 

1DB2还不支持嵌套函数和嵌套存储过程,此修改是最耗时同时最容易出问题的地方。

2) DB2里对FUNCTION的支持还比较弱,虽然已经支持OUT参数,但是调用方式必须是标准的赋值操作。虽然改法简单,不容易出错,但是有可能代码里大量用到,修改工作量可能会很大。

3PL/SQLpackage定义里还不支持Java Function。这个问题需要将Java Function提取出来放到DB2module里,同时为了支持OUT参数,需要将Java Function改成ProcedureJava function代码的提取,转换部署部分已经做完,因为将Function改成了ProcedureJava代码的return值要去掉,同时OUT类型参数要变成数组类型。

4DB2在部署的时候会经常碰到DB2 Crash的问题。

5)有些Oracle的内置包在DB2里不支持,比如DBMS_AQDBMS_APPLICATION_INFO,虽然有模拟Oracle的类似实现,但是功能不全,可能会有一些bug在里面。

6)对于NUMBERVARCHAR2DATE类型,在DB2系统表里存储的时候会转成DB2的类型,因此如果代码用到了类型比较就会出问题。

7)Oracle OCCI接口不能兼容,需要自己根据DB2 CLI模拟Oracle OCCI接口。

8)有些JDBC接口Oracle和DB2行为不同,比如executeQuery等。

9)DB2 JDBC不能识别函数作为列名的SQL语句。DB2里必须在函数后面加AS字句才能识别。代码里用的最多的地方是分页用的ROWID,需要熟悉的开发人员进行代码的修改,否则所有涉及分页的页面都无法显示。

修改前的代码:

ResultSet rs;

Statement stmt = conn.createStatement();

rs = stmt.executeQuery("select ROWID from test t");

rs.next();

System.out.println(rs.getString("ROWID"));

System.out.println("execute success");

System.out.println();

rs.close();

stmt.close();

conn.close();

修改后的代码:

ResultSet rs;

Statement stmt = conn.createStatement();

rs = stmt.executeQuery("select ROWID as ROWID from test t");

rs.next();

System.out.println(rs.getString("ROWID"));

System.out.println("execute success");

rs.close();

stmt.close();

conn.close();

10)不能创建类型为table和object的自定义类型。
不支持的代码如下:
CREATE OR REPLACE TYPE "LOAN_ADMIN"."T_ARRAY_LOG_QUEUE" AS TABLE OF T_LOG_QUEUE;
修改方法:需要将table和object类型的自定义类型封装到Package里,代码如下:
CREATE OR REPLACE PACKAGE "LOAN_ADMIN"."PA_TYPES" AS
TYPE "SMP_VDE_EVT_OCC_OBJECT" IS RECORD (
    eventId INTEGER,
    targetName VARCHAR2(128)
);
TYPE "ARRAY_TYPE_THREAD" IS TABLE of TYPE_THREAD INDEX BY INTEGER;
END PA_TYPES;

 

11)Create View里不能加Order By子句。
修改方法:
改成create view abc as select * from (select c1 from a1 order by c1)的形式。

12) JOIN的连接条件不能使用子查询语句

修改前:

select * from test t1 left outer join test2 t2 on t1.c1=t2.c1 and t2.c2 in (select 11 from dual)

修改后:

select * from test t1 left outer join test2 t2 on t1.c1=t2.c1 where t2.c2 in (select 11 from dual)

13)DB2不支持like后面跟函数

修改前:

SELECT * from test where c1 like NVL(?, c1)

修改后:

SELECT * from test where locate (NVL(?, c1), c1) <> 0

 

 

数据库迁移项目是风险很高的事情,建议广大客户和实施商采用专业服务,而不是自己从头摸索。有意向需要咨询从Oracle/SQL Server到DB2数据库迁移培训的个人或企业:

欢迎来电来信咨询:

联系人:王飞鹏
联系电话:13811817203
邮箱:
13811817203@163.com
QQ号:16198686
QQ群:186465431
     

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

1

添加新评论11 条评论

Priest_LeonPriest_Leon系统架构师99无限
2013-12-06 21:41
挺好的,顶下
jlandzpajlandzpa系统运维工程师广州华南资讯科技有限公司
2013-12-04 01:49
不错,感谢分享
hongyehongyehongyehongye数据库管理员哈尔滨银行
2013-10-26 18:38
学习了~顶~
id_taosicaiid_taosicai系统运维工程师软通动力
2013-10-25 10:40
这个话题很有意思,以后我也可能用得到,先谢谢了!
db2_louxldb2_louxl项目经理上海诺祺科技有限公司
2013-10-24 11:30
good 谢谢分享!
drdb2drdb2系统工程师se
2013-10-24 02:08
thanks for sharing
leobush1990leobush1990软件开发工程师neusoft
2013-10-23 09:48
daoguo525daoguo525系统工程师世纪五岳(北京)科技有限公司
2013-10-20 23:36
非常好
安卡妮娜安卡妮娜其它西南财经大学天府学院
2013-10-20 17:34
lxpeng163lxpeng163项目经理哈尔滨银行
2013-10-20 16:09
繁华如梦繁华如梦其它深圳某证券
2013-10-20 11:12
Mark!!!
Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广