232024.02

从Oracle数据库迁移到国产数据库的11个难点解析

2024.02.23

数据库自主可控落地在当前没有通用的行业参考,大多数企业缺少同业经验指导,可能发生选型错误,迁移过程中困难重重,有成本升高、项目延后等风险。本文来自社区举办的一次线上交流活动,由企业IT应用趋势项目联盟“数据库自主可控方向”课题专家组专家参与分享,并对活动内容的精华进行汇总,社区多位会员参与交流。希望来自同行的经验能够帮助大家少走弯路,高效克服难题。

执笔专家:苑华伟 卢丽欢 杨光

背景

近几年国产数据库以其高并发、海量数据、易扩展、高可用、易运维(一体化自动运维平台)等技术优势,以及其部署在普通硬件服务器之上的成本优势,在国内各个行业取得了广泛应用,成熟度也越来越高,关注程度也越来越高,在金融行业尤其是银行业数据库国产化替换的趋势越来越明显:在银行业数字化转型和高质量发展过程中,IT系统的飞速发展,而传统以Oracle为代表的集中式IT架构已经无法满足需求,像云平台、大数据、AI、微服务、分布式架构、敏捷前台、统一中台等技术架构的发展很好的契合了银行未来业务发展的需求,而国产数据库作为其中重要环节贯穿了整个前中后端,重要程度不言而喻,是未来银行IT架构转型发展的重要趋势;此外,金融行业国产化进一步推进并逐步进入深水区,数据库国产化是其中一项重要内容,数据库从传统Oracle迁移到国产数据库势在必行。

本文重点围绕企业在去O实践过程中遇到的难题进行交流探讨总结:


1、由Oracle数据库迁移到分布式数据库之后,关联查询的语句怎么解决?

【问题描述】由Oracle数据库迁移到分布式数据库之后,除了让尽量把需要关联的表按照相同的规则分布在一个节点外,现在系统的数据量都是5T以上的,不同的表已经按照不同的规则进行了分区,这些表之间的关联查询是应用必须要的而且频率很高,如果需要把所有的表按照统一规则去设置分布字段让同一用户下的资料都相同的节点上,这样的话改造就非常大,万一要回退也会非常麻烦,请问一下专家,这个问题还有没有其他好办法来解决复杂的关联查询的问题,又不会导致应用改造过大?

@hanfeng_twt SphereEx 数据库架构师:

解决上述问题有几个思路:

1.产品层面

有些分布式数据库产品,提供“自动分布式”能力,即可以实现数据自主分片,不再需要人为干预。这样在结构设计无需做太多修改。针对语句方面,也可以免改造或低改造完成迁移。当然这种方式还是要看业务复杂度,很难做到完全规避因引入分布式带来的改造成本。且针对复杂查询情况下,目标数据库是否能很好处理且保证性能也是需关注的。

2.设计层面

在设计方面,提前做好相应的改造评估工作。如对现有结构、语句通过工具扫描方式,获得当前的工作负载,针对分布式情况下做改造评估等。这种方式不会减少改造工作量,但会提前规划避免被动。这种也是我比较推荐的方式。

3.架构层面

针对复杂的Oracle查询,有些场景可考虑下移到大数据技术栈解决。后者针对复杂关联查询,会更为适合。但两者需解决数据同步问题且业务是否接受一定延迟,也需关注。

2、如果数据库较大,全量迁移时间较长,如何尽可能缩短停机窗口?

【问题描述】对于数据库容量较大的库,从Oracle迁移到国产数据库,全量迁移需要较长时间,而对于金融机构来说,停机窗口非常宝贵,如何可以缩短停机窗口是实施的难点之一,如果是同构数据库的迁移,比如Oracle迁移到Oracle,有比较成熟的工具实现全量和增量的迁移,前期先进行全量迁移,停机窗口时再进行增量迁移,可以尽可能缩短停机时间,但是Oracle到国产数据库,如何进行类似的全量和增量迁移,需要重点考虑?

@hanfeng_twt SphereEx 数据库架构师:

总结来说,是异构数据库间迁移的问题

1.提供常规的全量及增量数据迁移能力,这对于有效缩短时间窗口有益。目前已有很多厂商提供此类能力。但需要注意的是,从集中式架构到分布式架构还可以;反之仍有一定局限。

2.提供全量及增量数据对比能力,满足对数据一致性的检验能力,这对于实施切换是重要参考依据。此外包括差异数据的正向、反向的补偿能力,也是需要的。

3.由业务逻辑方面提供一定的兼容能力,可满足短时间系统间迁移的数据补偿能力,有助于缩短窗口。

4.架构设计方面,提供多种数据同步考虑,除了数据库外,还可以考虑如应用报文、网络协议等方面的同步机制,作为有益的补充。

@huawei851120 江苏省农村信用社联合社 数据库运维工程师:

有两种思路:

1.先对Oracle的大表进行改造,分为历史表和当前表。把历史表先期迁移到国产数据库,停机窗口内再把当前用的表迁移过去。这种用法比较推荐;

2.利用同步工具。几家大厂的国产数据库,都有自己的数据同步工具,可以先期进行数据同步,但不能同步DDL。这个阶段不要进行Oracle表结构的表更。投产窗口内,把应用停掉后,等数据追平就可以了。

@刘炜钰 城银清算服务有限责任公司 应用维护:

1.截止到一个时间点可以提前迁移历史数据,比如窗口前一周或者提前1、2天;

2.到了停机窗口,业务停运后补增量数据;

3.做好全量数据的检查,补完增量后,新老库数据量对比,做最终确认,这样就能大大减少数据迁移时间 。

@yata52 中国人寿财险 数据库管理员:

目前我们接触的国产数据库厂商都有了适合自己的全量初始化加增量同步方案,有的是利用自有工具,有的是利用常见数据迁移软件,都能做到在切换前数据实时同步几乎无延迟。但是总结下来,迁移的过程还需要重点考虑这几个问题:

1.如果源库较大,为了保障全量初始化成功,需要考虑适当调大undo表空间,为了保障迁移时对生产影响较小,尽量使用物理备库抽取,全量迁移时合理分组初始化。如果是单表过大又没有物理备库的情况,可以考虑使用更高效的工具(数据泵等)将单表迁移至Oracle中转库(不承载业务)再慢慢导入到国产数据库。

2.如果迁移过程中使用了kettle、ogg、平面文件多种技术组合实现,上线前一定要对数据做验证,防止出现中文乱码。

3.各家都实现了实时增量同步,目前切换过程中占用停机时间的主要是这两个步骤,一是数据静态后的数据检验时间,二是反向同步启动前的配置和检查工作。

3、国产数据库分集中式和分布式,Oracle迁移至集中式还是分布式场景?

【问题描述】国产数据库有提供集中式模式和分布式模式两种,集中式省去了数据分布方面的难点,更容易实现迁移,但是性能、容量和扩展性受限,而分布式数据库改造难度相对较大,但性能、容量和扩展性优势明显,因此,如何更加具体业务场景选择合适的数据库?

@huawei851120 江苏省农村信用社联合社 数据库运维工程师:

1.首选无论是集中式还是分布式,都尽量采用大厂的产品。因为数据迁移工作,看似没什么大不了,一旦出问题后后果很严重。大厂的集中式和分布式产品一般都有数据迁移工具,并且在很多客户那使用过,迁移都会比较方便,但没有想象的完美。

2.如果是小库,迁移至集中式会比较方便,通过工具直接可以迁移。如果是交易量比较大、数据量比较大的库,推荐采用分布式数据库,集中式的性能肯定不如大厂的分布式数据库产品。

3.如果库有非常多的存储过程(几十个,乃至几百个),还是采用集中式比较好。分布式数据库,尤其是基于MySQL的对存储过程兼容性不太好。

@yata52 中国人寿财险 数据库管理员:

首先总结下我司所使用的两种数据库特点:

集中式数据库:体系结构与Oracle类似,语法兼容度高、对服务器无要求、数据迁移成本小、运维规范可基本沿用。单集群性能上限受限于X86服务器算力,相比小型机+Oracle的组合仍存在一定差距。

分布式数据库:使用分布式协议和LSM-Tree数据结构,需要修改为Mysql语法、对服务器性能要求较高、数据迁移成本较高、运维规范需重新建立。单集群库性能可通过扩充服务器进行扩展,算力可突破小型机+Oracle的组合。

针对以上两种特点,我们的替换场景如下:

1.切换前使用虚拟机运行数据库的中低负载系统,替换为集中式数据库。

2.切换前使用小型机或者多台物理机运行数据库的中高负载系统,替换为分布式数据库。

@lulihuan1987 张家港行 数据库管理员:

国产数据库集中式模式迁移难度较小,适配容易,特别是一些特殊数据库对象也可以支持,比如函数和存储过程,对于性能,容量和扩展性要求不高,单台数据库服务器足以支撑的业务场景,可以采用。而分布式模式对于数据库比较大,高并发,需要根据业务需求可以扩展的业务场景,单台服务器无法支撑的场景。无论是集中式还是分布式模式,均支持跨机房级容灾和节点高可用等特性。

@hanfeng_twt SphereEx 数据库架构师:

从Oracle迁移到国产数据库的选择路线:

1.迁移目的:首选需要关注的是迁移目的,是为了解决性能、承载量,还是为了满足自主可控。针对前者的话,考虑分布式架构更多;后者,则更倾向于考虑国产集中式架构产品。

2.应用适配:次之要考虑应用适配问题。如果应用对Oracle有较深度的依赖,则需优先考虑兼容度好的产品,相对而言集中式架构产品在这方面有些优势;反之,则可不将此因素作为选择要素之一。此外,针对分布式架构,需要考虑如数据分片等问题,也需一并考虑。某些系统依赖外部厂商开发,出于尽量减少开发量的初衷,集中式架构更有优势。

3.运维适配:现有运维体系是否对分布式架构有一定经验或者已具备相关人员储备,这对于选择这一架构很重要。这其中包括从基础设施、备份恢复、故障处理、性能调优等多方面。

4.业务连续性:相对集中式架构而言,分布式在整体稳定性等方面还需验证。因此在选择之初,要将整体可用性作为考虑要素之一,是否有专项预案解决需考虑。

4、正式替换原有数据库后,如何保证国产数据库写库的准确性?是否有异构数据库之间的数据稽核?

【问题描述】在双轨运行过程中,如何保证国产数据库写库的准确性?我们之前测试的时候发现有些国产数据库保存的精度与Oracle不一致。是否有异构数据库之间的数据强一致性的稽核?

@huawei851120 江苏省农村信用社联合社 数据库运维工程师:

据我了解,应该是没有的。本人也是希望有,这样可以防止国产数据库出现天大的问题(数据不一致)的时候,我们客户能及早的发现,不至于酿成大错。可是目前国内应该没有这样的异构数据库之间的数据稽核。小厂商都是基于MySQL和PG开发的,不值得大厂去开发工具稽核它们。大厂的数据库核心技术都是保密的,不会给别的大厂去稽核。

@我是个小胖子 国泰君安:

根据我们前面的应用经验,这种稽核一般是有两种方式。

一是由数据库厂商提供相关的工具,来核对两个库的数据一致性,比如两边分别导出csv文件(排除自增id,时间戳等字段),然后进行比对,也可以以oracle数据库基准,用唯一键定位国产库的行数据,然后进行比对。

二是由业务每日导出当日的增量数据,然后由业务方自行比对。

5、风险控制方面考虑,例如白名单灰度迁移,回退方案等?

【问题描述】迁移过程中风险必须是可控的,由于是对于重要在线业务系统,一方面要确保业务系统尽可能短暂的影响,又要确保出现问题能够快速应对或者回退,该问题难点在于涉及数据库的切换,如果只涉及应用,那么可以通过灰度发布实现,出现问题也可以及时回退,而数据库的迁移是否可以借鉴类似的思路去实现白名单灰度迁移,出现问题快速回退,整个过程中Oracle和国产数据库之间的数据如何处理?

@huawei851120 江苏省农村信用社联合社 数据库运维工程师:

从我们的经验看,灰度迁移是个危险的想法,哈哈!真的,容易把数据搞脏掉,不建议这样做。虽然整体数据迁移,风险高,但是容易保持数据一致性。一旦失败后,可以追日志来找到数据一致点。至于您担心的事情,我个人的意见是:

1.提前把国产数据的环境搭好,小库要提前两周,大库要提前一个月。

2.在生产上,切换投产窗口前提前做几轮的迁移测试。比如9月1日迁移,在8月中旬下旬各做两轮的迁移,在生产上做的话,注意窗口,以防对现有系统造成影响。可以选择深夜交易低谷进行。

3.每轮迁移完成后,对数据进行校验和比对。

@yata52 中国人寿财险 数据库管理员:

目前我们接触到的国产数据库厂商暂时还做不到同时双向同步,即同一个表内的数据Oracle的变更向国产写,同时国产的变更向Oracle写。但是目前都实现了单向同步, Oracle的变更向国产写没问题, 切换之后国产的变更向Oracle回写也没有问题。针对快速回切,实践中我们会用这两种方式:

1.针对核心系统,切换后开启反向实时同步。上线前准备好回切方案,数据库部分主要是涉及序列的变更和数据校验脚本。数据库切换之后立刻开启反向回退,保障国产数据库内的变更可以准实时的写回原Oracle数据库。由于中间件切换异构数据库的数据源需要重启,所以切换后老应用的中间件数据源不调整,仅从F5中摘掉,需要回切时候完成数据库切换动作后直接把老应用挂回F5。

2.针对可自行稽核并补录数据的系统,我们是直接在新环境搭建新库并按照业务团队的要求导入某一时间的数据,业务切换后数据库层不提供数据实时同步服务,直接将Oracle数据库的表空间设为只读避免流量没有切干净。

6、数据库很大,迁移窗口又相对有限的数据库迁移应该怎么实现?每个数据库用户基本都在3T级别。

@huawei851120 江苏省农村信用社联合社 数据库运维工程师:

这种大库是很难办的。常用的方法:

(1)花力气对原Oracle库进行改造,把表分为历史表和当前表。比如3个月前的数据放1个表或几十张表里,当前交易进行增删改查的作为一个表,给当前交易用;

(2)先对历史表进行数据迁移;

(3)投产窗口对当前表进行迁移,可能3T里面只有300G~800G左右,这样才能控制投产的是迁移窗口时长。

@yata52 中国人寿财险 数据库管理员:

可以考虑采用全量+增量的方法进行数据同步,停机窗口前将增量延时控制在分钟级别。

达梦:自有工具HS。

Oceanbase:自有工具OMS。

TiDB:外部工具Goldengate。

7、从Oracle迁移到信创数据库后的应急预案?

【问题描述】对于一些大企业的数据库从传统的Oracle迁移到信创。很多时候会存在一种顾虑。就是长久的性能和可靠性,比如在迁移到了信创数据库,在短时间内的性能指标和功能都满足了需求。但有些业务可能是周期性的。有些问题也可能是累积后出现的。这种情况可能会导致割接一段时间后数据库出现问题。对于这样的顾虑和可能发生的风险。有哪些应急预案呢?

@lulihuan1987 张家港行 数据库管理员:

上线是需要制定应急预案,出现问题要把数据倒刷回去紧急回退,对于已经上线并运行一段时间出现问题想回退,需要满足两个条件。第一应用支持两种不同数据库,支持Oracle和国产数据库,并且应用两套代码都支持同步开发,可以更改配置数据源后能切换数据库。第二,两个数据库间数据准实时同步。

@pysx0503:
理论上是这样。可是有些老业务因为年代久远,缺少技术支撑,信创更新是基于业务的全新开发,在这种情况下。可能很难做到两套代码的同步,甚至有不少案例都是硬着头皮在没有应急预案的情况下进行的割接升级,更新到信创数据库之后如果一段时间后出现了问题。老旧的业务应用和数据库可能因为缺少技术支持和原始资料而无法做到紧急回退。这种情况请问有什么更好的办法避免吗?
@lulihuan1987 回复 pysx0503:
这个不是理论上的,我们银行2019年上线的新核心就是采用该方案并且同步运行了一年,当时投入了很多资源,包括应用厂商,数据库厂商以及我们行方。要做到运行一段时间后还能回退,目前我们就是这么做的。不过现在三年过去了,都在成熟,只要做好充分测试,不需要应急回退的了,也不现实,成本太高了。
@yata52 回复 pysx0503:
还有一种思路是上线前在信创环境导入真实业务流量,充分验证功能及性能。老系统按照现有节奏进行监管升级,验证期间新环境可以不升级新功能,只在验证流程完毕后追平功能。

@hanfeng_twt SphereEx 数据库架构师:

1.对于核心的系统,需考虑双发机制,即并行两套系统运行,可保证随时有后备系统可选择。

2.对于非核心系统,可考虑在异构数据库同步方案,即保证数据不丢失有备用数据库可用。

3.从应用角度来讲,弱化对数据库的依赖,尽量使用通用方法,有助于回切。

8、Oracle中对于频繁查询更新的大表如何实现迁移优化?

【问题描述】原来使用的Oracle数据库时,由于其成熟的查询优化器,对于频繁查询并更新的大表而言,效率可以接受,业务也能接受,例如交易记录,所有的交易均需要插入该表,而部分交易可能又要频繁查询该表甚至频繁更新该表,当表容量达到一定大小时,从Oracle迁移到国产数据库可能存在效率问题,一旦该表出现卡顿,所有交易都有影响,后果非常严重,因此在迁移过程中对于这类频繁查询更新的大表需要如何考虑?

@huawei851120 江苏省农村信用社联合社 数据库运维工程师:

根据经验有以下建议:

先对Oracle库进行优化改造,对大表改造为分区表,缩小每个分区表的大小。然后为改Oracle库建立ADG读库,将读交易改造至读改ADG库。优化完成后,再进行国产化改造就很方便了。甚至可以分阶段先改造读交易至国产数据库,再改造写交易至国产数据库。

最后:如果一个系统在Oracle上运行就有比较多的问题,不要试图通过改造成国产数据库来解决该问题,可能会把问题放大。

9、Oracle到国产数据库迁移后数据如何作对比,比如大字段等?

【问题描述】数据迁移后需要进行源库和目标库的数据比对,以确保数据迁移准确性,但是由于是数据库异构,字段类型会发生变化,数据比对往往没有那么容易,记录数比对相对来说比较容易实现,但是字段级别的比对难度和效率很难达到平衡,例如大字段类型等,所以迁移后数据比对如何实现,确保数据库一条一个字段都不能有问题?

@yata52 中国人寿财险 数据库管理员:

.目前国产的数据同步工具已经在逐步适配国产数据库,可以依托这些工具自带的对比工具。

2.在没有外部工具的情况下如何平衡效率和全面性,可以考虑上线前的测试阶段对数据进行全面校验,在正式迁移停机窗口内效率优先(目前国产数据库厂商已有对比脚本,仅对比对象数量、状态、条数、主键)。

3.测试阶段可以要求开发团队或者业务团队联合验证,一些由于迁移引起的大字段丢失、乱码、精度错误等问题暴露的会比较快,排查起来更高效。

@lulihuan1987 张家港行 数据库管理员:

一方面可以依靠数据库厂商提供的同步平台,但是目前大字段的比对没有太好的办法,可以试着增加字段求该行md5值的方法试试。

10、Oracle迁移至国产数据库后,如何保证数据的完全一致性?并行期间,如何将数据回写Oracle?

@lulihuan1987 张家港行 数据库管理员

Oracle迁移到国产数据库后,如果Oracle想要作为备份继续使用,那么双写和数据同步都是可以的,具体的方案也需要结合业务系统去做。两个数据库间数据的完全一致性需要靠同步工具或者编写脚本去检验,一般以同步工具为主,脚本为辅。

@yata52 中国人寿财险 数据库管理员:

具体哪种方式需要看应用支持双写的难度。说一个我们碰到的应用双写难点,部分流水号是通过序列生成的。为了加速序列的使用Oracle和国产库都加了cache,如果是简单的通过nginx将业务流量镜像,两边取到的序列值就难于保障是一致的。创建订单的流程都能完成,只是生成的流水号不一样,但是对于根据流水号修改的业务,流量复制到备端就会异常。

11、迁移至国产分布式数据库后分表实践方案?

【问题描述】各位老师,迁移至国产分布式数据库后的分库分表方案,一直困扰着我。也查阅了很多相关资料,但是还是感觉没有一个满意的可落地方案。因此提出几个具体问题,希望各位老师能够解答,也希望各位同业一起交流。

1.尽量保证单库查询的原则是指的一个交易事务范围内,还是单个sql范围内呢?

2.一笔记账交易涉及多类表:如账户表,参数表,凭证表,流水表,机构表等。如何合理划分分片键呢,保证尽量单库处理。能否有具体的案例参考?

3.如何衡量分库分表策略合理呢?是否有类似单库sql占比,两分片sql占比等类似的指标进行衡量呢?

4.是否可以提供某个具体案例,交易描述,分片策略等,帮助我们进行参考?

@huhu097 云南红塔银行 DBA:

先考虑表的性质,是在线交易型(存放在线交易数据),还是分析型(历史数据归档和交易日志等),在线交易型的表分区优先考虑事务处理逻辑,避免分布式事务,考虑和其他表关联的情况,来确定分区键以及分区的方式,索引的创建和使用需要考虑表分区键,在线交易系统单笔交易涉及sql数量一般都比较多,单个事务内包含多条sql,建议分析交易处理逻辑以及sql涉及的表结构,再做分区。分析型的表优先考虑历史数据归档以及清理的问题,另外还有历史数据查询的效率问题,OceanBase现有的表组,支持全局唯一性索引(可以不带分区键),广播表,对分表非常的友好。

@lulihuan1987 张家港行 数据库管理员:

通常单sql查询索引合理的情况下不会有问题,这里的单sql指的是单表的sql,如果带上分片字段的话是最优解,只操作单节点。单sql的更新,update和delete需要带上分片字段,否则存在跨节点更新,会有效率问题,对于不支持全局一致性的数据库来说,可能还有一致性问题。insert时涉及跨节点更新时也要注意。两个以上表操作sql设计是难点,总的原则就是避免跨节点数据流动,能拆就拆,不能拆的关键字段必须是分片字段。

@hanfeng_twt SphereEx 数据库架构师:

1.所谓单库查询,是指语句查询可以精确到某个分片中,这样的效率最高。从事务处理角度来看,能否限制在某个分片内(即本地事务),也是效率最高的。

2.具体的分片策略没有一定之规,一方面可选择业务的共性部分作为分片键,一方面数据量不大又参与到业务中的,也可考虑全局表(或广播表)的方式。

3.无法完全杜绝分库分表,只能尽量减少。具体比例取决于业务及分片策略。

4.可参考北京金融联盟最新发布的单元化策略指南。