达梦VS金仓:真正做一次Oracle迁移,才知道工具链有多重要
前段时间做国产数据库选型,有人问了我一个问题:
"达梦和金仓到底选哪个?"
这种问题其实挺难直接回答。
如果只是新建一个普通业务系统,表不多,也没有多少复杂SQL,两边基本都能做。真正把差距拉开的,往往是那些已经运行了很多年的老系统。
尤其是Oracle迁移。
表能不能建出来只是第一关,后面还有存储过程、函数、触发器、程序包,以及藏在Java代码和Mapper里的SQL。
这些东西才是真正花时间的地方。

一、1200多个存储过程,让选型变得没那么简单
去年接触过一个Oracle国产化替换项目。
系统运行时间比较久,业务逻辑也比较重,数据库里面有1200多个存储过程。除了常见的PL/SQL,还用了不少游标、函数和Oracle特有写法。
选型阶段考虑过达梦和金仓。
如果只是看产品资料,其实很难判断。
两边都支持Oracle迁移,也都有自己的迁移工具。功能列表拿出来一对比,你会发现很多地方甚至差不多。
所以后来还是决定拿真实业务做POC。
这里我觉得有个经验特别重要:
国产数据库选型,千万不要只建几十张测试表,然后跑几个SELECT就结束。
这种测试基本看不出迁移难度。
真正应该拿出来测试的,是系统里那些你平时最不愿意碰的SQL和存储过程。
我们当时也是这么干的。
普通CRUD基本没什么悬念,真正开始拉开工作量差距的是复杂数据库对象。
有些Oracle代码迁过去之后基本不用动,有些则需要重新调整。单看一个存储过程可能只多半天、一天,但当数量变成几百甚至上千以后,这个差距就非常明显了。
这也是我后来越来越关注迁移工具链的原因。
二、数据库迁移最贵的其实不是搬数据
以前没做过大型迁移的时候,我总觉得数据库迁移最麻烦的是数据。
几个TB怎么搬?
迁移过程中业务还在写怎么办?
全量迁完以后增量怎么追?
这些当然重要。
但真正做下来会发现,数据反而是比较容易标准化的一部分。
真正难估的是代码。
比如一个Oracle系统有1000个存储过程。
到底有多少能直接迁?
多少改几个函数就行?
多少涉及Oracle特有机制,需要重新实现?
项目开始之前如果回答不了这几个问题,后面的工期基本就是猜。
更麻烦的是,这些SQL不一定全部存在数据库里。
一部分在存储过程中,一部分在MyBatis Mapper里,还有一部分可能直接写在Java代码里。再老一点的项目,甚至还能翻出来一些没人敢删、也不知道还有没有人在用的SQL脚本。
所以后来再看迁移工具,我第一个关注的已经不是"迁移速度多少MB/s",而是:
它能不能先把这些东西找全。
三、这也是我觉得KDMS比较有意思的地方
金仓KDMS首先做的不是搬数据,而是迁移评估。
简单理解,就是先给源系统做一次体检。
数据库里的表、视图、触发器、约束、序列、函数、存储过程这些对象先采集出来,然后分析里面有哪些内容迁移到金仓以后可能存在兼容问题。
除此之外,还可以把应用侧的SQL一起考虑进去。
比如项目使用MyBatis,Mapper里面就可能藏着大量SQL。如果只分析数据库对象,这部分实际上是漏掉的。
这一点在真实项目里很重要。
我之前就遇到过数据库迁完、测试也差不多结束,结果某个边缘功能一点就报错。
最后查了半天,发现SQL根本不在数据库对象里,而是开发几年前直接写在代码里的。
这种问题最烦的地方不是难改,而是出现得太晚。
如果能在迁移开始之前把它扫出来,哪怕最后还是需要人工修改,项目都会轻松很多。
四、达梦DTS其实也不是不能做
这里也得说清楚。
达梦DTS本身同样具备数据库迁移和评估相关能力,并不是说用了达梦就只能靠人工迁。
它可以对源数据库对象进行分析,也能处理SQL评估。针对MyBatis、iBatis等应用场景,也有相应的SQL分析方式。
所以如果只列功能清单,两边其实很难简单分出高低。
真正让我感觉到差别的地方,还是落到具体项目以后:
你的系统里到底用了什么。
如果只是表、索引、普通SQL,两边差异可能没有想象中那么大。
但Oracle老系统经常不是这样。
真正让人头疼的是各种历史存储过程、程序包、复杂游标以及一些Oracle特有的函数和行为。
这个时候,比"支持Oracle迁移"这句话更重要的是:
到底支持到什么程度?
哪些能直接过去?
哪些工具可以自动处理?
剩下多少需要人改?
这几个问题不跑真实业务代码,很难得到答案。
五、我现在看迁移评估报告,也不太迷信"兼容率"
很多迁移工具最后都会给一个兼容率。
比如90%、95%、98%。
这个数字可以看,但不能只看这个。
举个很简单的例子。
1000个对象里面有980个兼容,看起来兼容率98%。
但如果剩下20个恰好都是两三千行的核心存储过程,那这20个对象可能比前面980个加起来还难处理。
反过来也一样。
有100个SQL被判断需要调整,但只是函数名称、数据类型或者分页写法存在差异,批量处理以后可能很快就结束了。
所以真正做迁移方案的时候,我现在更愿意看明细。
哪些是不兼容对象?
集中在哪几个系统?
是普通SQL多,还是存储过程多?
有没有核心交易链路?
有没有大量Oracle特有功能?
这些东西搞清楚以后,那个兼容率才真正有意义。
六、工具能解决80%的问题,剩下的还是得靠人
数据库迁移做到最后,不可能完全自动化。
这一点不管用达梦还是金仓,我觉得都一样。
比如一个几百行的存储过程,里面既有业务判断,又有游标,又调用其他函数。
工具可以告诉你:
这里可能存在兼容问题。
甚至可以帮你转换一部分。
但这段逻辑迁过去以后业务结果是不是完全一致,最终还是要测试。
所以我现在对迁移工具的要求反而没以前那么"理想化"。
我不要求它什么都自动完成。
只要能做到两件事情,就已经能省很多时间:
第一,把问题尽量找全。
第二,把问题尽量提前。
一个问题在项目第一周发现,和上线前一周发现,处理成本完全不是一个概念。
七、真正值得比较的是整条迁移链路
这次选型之后,我还有一个比较明显的感受:
不能只比较数据库内核。
因为企业做国产化替换,不是安装一个数据库软件就结束了。
前面要评估,中间要做对象转换和全量迁移,业务不停机的话还要考虑增量同步,迁移结束以后还要验证数据和SQL。
金仓这边我接触比较多的是KDMS、KDTS以及后续同步相关工具。
它们分别解决不同阶段的问题。
KDMS更偏迁移之前,把兼容性和改造量先摸出来;KDTS负责后面的结构、对象以及数据迁移;涉及不停机迁移时,再考虑增量同步。
达梦也有自己的DTS等迁移工具。
所以实际选型的时候,我现在更建议把这些工具全部算进去。
不能只问:
"哪个数据库跑得快?"
还应该问:
"我现有这个Oracle系统迁过去,到底要改多少东西?"
对于存量系统来说,后面这个问题可能更值钱。
八、不要拿网上的DEMO替自己的项目做决定
网上经常能看到各种国产数据库对比。
A兼容多少语法,B支持多少功能,谁的迁移效率又是多少。
这些东西可以作为参考,但真到了项目选型,我觉得都不能代替POC。
因为每家公司Oracle用法完全不一样。
有的系统只是把Oracle当普通关系型数据库使用,SQL也比较规范。这种系统迁到国产数据库通常没那么痛苦。
但有些系统大量依赖PL/SQL,业务逻辑甚至有一半放在存储过程中。
这完全是另外一种难度。
所以真要在达梦和金仓之间做选择,我反而建议别急着看结论。
从生产库抽一批最有代表性的对象出来:
核心表来一些。
复杂视图来一些。
最大的几个存储过程拿出来。
Oracle特有函数比较多的SQL也拿出来。
再把应用里的Mapper扫一遍。
然后分别跑一次。
到这个时候,谁需要改50处,谁需要改500处,其实已经不用别人告诉你应该选哪个了。
九、最后说点做项目之后的感受
以前做数据库选型,我比较关注性能参数、并发、TPS这些东西。
现在如果面对的是Oracle国产化替换,我会把"迁移改造成本"放到很前面。
原因很现实。
数据库采购成本是看得见的,服务器成本也是看得见的。
最容易被忽略的其实是人。
如果一个项目因为兼容问题多出几百个人日,开发、DBA、测试全部要跟着投入,这部分钱最后可能比数据库本身还贵。
所以达梦和金仓到底谁更适合,并没有一个脱离业务场景的固定答案。
至少在我接触的这类Oracle重度使用场景里,我会更关注金仓的Oracle兼容能力和KDMS这一整套迁移评估流程。
但换一个系统、换一批SQL,结论完全可能不一样。
数据库选型最靠谱的方法,始终不是看谁PPT上的兼容率更高,而是把自己最难迁的那批代码拿出来跑一遍。
能不能迁,改多少代码,要投入多少人。
这三个数字跑出来以后,选型其实就没那么纠结了。