为这一段时间国产化数据库迁移做个总结

背景

近年来,随着金融、电信等行业对数据库自主可控要求的提升,越来越多的企业开始从传统商业数据库向国产分布式数据库迁移。

软件基础设施国产化,这是好事,只是辛苦我们这些一线开发者。

先说一下背景,这是一个运行了近30年的老系统,数据承载在Oracle之上,在这一轮国产化之中,轮到了这个老系统,在甲方的要求之下,这次迁移不只是迁移数据库这么简单,而是整体上云,运行机器从原来的独立的Windows Server 2003迁到K8S,数据库从Oracle迁移到中兴数据库,在这个老旧的系统框架之下,带来了种种困难以及问题。

在这个过程中,我只负责业务系统的代码开发,其他的数据迁移、系统准备均由其他专业团队负责。

迁移记录

所有的说明基于以下的版本,仅代表以下版本

GoldenDB版本:V6.1.03.05P2T3
JDBC驱动版本:5.1.46.42

在开发环境一轮又一轮地测试过程中,总结如下

GoldenDB数据库与Oracle的兼容性不错,大量非标sql无法修改可以正常正确运行在GoldenDb,这减轻了我不少的开发工作量。

老旧系统在经过这么多年的开发,剩下的SQL修改主要集中在以下几个方面:

1、嵌套子查询

系统中存在着一部分select字段中,出现了(select abc from tab where column1 = b.column1) as state这一类的嵌套子查询, 这一类非标准SQL在Oracle中正常运行,但无法在GoldenDb运行,会返回SqlNode Err,原因不明。

这一类使用字段进行翻译查询的嵌套子查询有两种解决方法:

  • 函数化,这是最简单的方法,我采用的方法
  • join化,不常出现的sql,我采用的这个修改

2、关键词等效替换

在Oracle中,unpivot关键词对于指定的每一组列,都会生成对应的行。但这个关键词以及功能,在GoldenDb跑不通过。

修改方法,使用常规标准的行转列语法,也就是union all。

3、函数性能

部分数据库函数里面嵌套多层子查询,要么报错,要么性能慢到无法忍受。

修改方法,去掉不支持的语法,并把嵌套使用exists或者join修改,部分树类查询改用平行字段替代,最终达到秒级响应,原来是分钟级响应,提升巨大。

4、索引效用

大量的时间查询是使用to_char对时间字段进行转换之后再做对比,如to_char(createdt, ‘yyyyMMDD’) = ‘20250501’,这一类对字段进行了相关的计算,是索引的大忌,会导致索引失效而走全表扫描。

修改方法:修改sql语句为区间查询:createdt between to_date(‘20250501’, ‘yyyyMMDD’) and to_date(‘20250501’, ‘yyyyMMDD’)+1,这样就是区间查询,查了执行计划确实会走索引,速度快了几个数据量级,特别是针对数据量几千万的大表,很明显。

like类型的sql,大量使用了前后模糊匹配(like ‘%abc%’),索引失效,业务能修改为后模糊匹配则修改。

5、语法重整

部分sql语句,引用了goldendb关键词,如ssl、remain,需要套上“号。

部分SELECT后添加hint /+join_order(oc,oi,ppp,ga) no_join_index(oi offer_item_seq)/,固定执行计划

不支持float数字类型,修改成decimal或者number标准数字类型

6、驱动数据类型

由于CLOB这两种大数据的字段类型,转换为LongText,但这个类型在驱动层面返回到Java是Byte[],而不是原数据库的String,导致了不少数据展示面B[@xxxxx]

修改方法:

if (obj instanceof byte[]) {
    return new String((byte[]) obj, Charset.forName("GBK"));
}

总结

在本次迁移的过程中,我能感受到GoldenDB经过了这么多年持续开发与改进,对Oracle的兼容已经做得相当出色,性能也足够本系统使用,而且还是一款分布式数据库,当然,本系统的数据量也没大到上百亿,无法确认GoldenDB在上百亿数据量的支撑性能。

在这里愿国产基础软件越来越好。

这样的迁移,不想再来第二次。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Scroll to Top