本文来自微信公众号“白鳝的洞穴”,作者/白鳝。
做数据库替代,兼容性分析是其中的第一个步骤,很多用户这一步没有认真做,真正开始做数据库替代的时候就会遇到一个一个的坑,填起来相当累。如果应用系统是重新构建,或者有足够的经费进行应用重构,那么兼容性问题不算个大问题,如果你想省点钱,那么兼容性分析还是要做得周到一些比较好。
数据库兼容性分析首先要分析字符集和时区等“小问题”,说是小问题,实际上也是容易被忽略的。国产数据库一般都会支持我们所需要的时区和字符集,因此测试一下数据导入后的生僻字是否能正常显示基本上字符集的问题就不大了。不过如果今后存在新旧数据库进行数据交换的场景,那么生僻字在数据交换中是否能够正确被复制过来也是要去认真测试一下的。如果存在dblink访问,还需要测试一下dblink中是否能正确的读写生僻字。
时区的测试也是类似,如果你的系统不存在多时区数据交换的问题,那么测试一下数据导入后时间是否正确,以及在DBLINK访问时获取的远端时间是否存在时区偏差就可以了。存在多时区数据交换的问题的用户,那么就要认真测试一下多时区转换是否正常。
第二个需要分析的是数据类型的兼容性。数据类型的兼容性是最重要的一环,Oracle数据库的数据类型十分丰富,一般国产数据库很难做到数据类型的一对一兼容,大部分从Oracle向国产数据库迁移时都存在类型转换的问题。其中最主要的是PFILE、XMLTYPE等数据类型。如果你的系统是90年代末开发的,那么有一定的概率会使用嵌套表或者自定义类型。如果这样,目前恐怕没有哪个国产数据库能够完全支持,此类应用最好的选择是暂时不要迁移了。因为很可能开发商都已经找不到了,而且应用迁移时,PL/SQL的兼容性也是十分成问题的,因为国产数据库虽然有不少兼容oracle的PL/SQL,但是自定义类型好像都不支持。在测试数据类型的兼容性时,如果你存在nchar/nvarchar等类型,那么就要十分小心了,编码上的差异可能会导致数据迁移过来会不一样,另外此类环境中,如果还需要和老系统进行数据复制,那么数据复制工具是否能够完成自动转换也是一个需要认真测试的内容。另外还要注意char字段的填充问题等一系列小问题。
第三个需要分析的是索引,Oracle数据库的索引其实很简单,不外乎B树(包含反转键、函数索引等变种)、位图、位图连接索引等几种。因此在索引方面哪怕兼容性不高,也大多数能够找到解决方案。索引的问题大部分会涉及到性能问题,另外就是不同数据库的索引在处理空值方面会有些不同。如果有些特殊的应用,那么需要换种方法来提高性能。
第四个需要分析的是序列号、自增字段、物化视图、触发器、全局临时表等特殊功能。Oracle和国产数据库会有些不同,有些时候需要通过修改应用来适应新的数据库。不过一般来说大部分国产数据库都具有类似的功能,哪怕没有的话,也可以通过一些技术手段来实现,只不过这种外挂式实现,性能方面可能会存在一些问题。
第五个方面是事务隔离级别和MVCC的兼容性。分布式数据库在事务隔离级别上和Oracle有所不同,一般情况下我们的应用只使用read commited事务隔离级别,这是几乎所有数据库都必须支持的事务隔离级别。不过如果你的应用用到了其他的事务隔离级别,正巧你又想使用分布式数据库,那么你就要认真测试下你的目标数据库的事务隔离级别和你目前在Oracle上用的事务隔离级别是否完全一致。
第六个方面是SQL语法的兼容性,Oracle并不十分严格的遵循SQL 1999等国际规范,而且早期的Oracle数据库版本中存在大量的自己风格的SQL。不过如果你的应用能够修改,那么这些问题也并不太大,不兼容的SQL的数量一般来说不会太多。见到最大不兼容的是dual表、insert select等语法方面的不同,还有就是序列号的取法,一般来说解决起来并不困难。另外要注意的是,如果你的应用中有不少统计分析方面的SQL,那么要注意的是统计函数和窗口函数方面的兼容性,你用到的统计函数和窗口函数有可能在某些国产数据库中并不支持。
第七个方面是hint、sql profile等优化SQL执行计划的能力,这种能力是必须的。因为系统迁移后可能会有一些SQL无法生成好的执行计划,从而导致性能无法满足应用需要。此时只能通过这些手段去做优化。Hint的功能与有效性都是需要认真去分析的,这些保命的手段如果不能起作用,那么系统切换后就麻烦大了。
第八个方面是PL/SQL的兼容性,目前国产数据库有不少都支持类似ORACLE PL/SQL的语法,不过大部分只能支持常用的简单语法,语法支持度不超过80%,一般在60-70%之间。如果你的应用使用的都是PL/SQL的常见功能,那么今后改造起来工作量也不大。甚至有些国产数据库并不具备PL/SQL,但是有存储过程转换工具。你的应用并不是重度使用存储过程,那么迁移的工作量也还是可以接受的。
第九个方面是表连接的方式与限制条件。Oracle在NESTED LOOP/HASH JOIN/SORT MERGE JOIN等方面的能力超强,国产数据库或多或少都会存在一些问题。有些SQL虽然不经过修改就能够在国产数据库上跑,不过性能恐怕不尽如人意,必须进行改写。你需要把你们业务系统中的一些常用的表连接比较复杂的SQL或者各种种类的表连接SQL都在新数据库上用模拟真实数据的数据量跑一跑,看看那些SQL在执行计划上存在问题,必须改写,并根据需要改写的数量评估是否可以接受这种数据库。
第十个方面是数据库导入导出、备份/恢复等方面的基本能力,是否与你目前的备份环境相兼容。
第十一个方面是高可用切换的便捷性与RTO/RPO方面的指标,数据库厂商标称的数据只是考虑了十分有限的场景,而你的应用场景很可能有所不同。如果有条件的话模拟生产环境做一做测试还是十分必要的。
第十二个方面是系统包的兼容性,一般来说,国产数据库的系统包和Oracle存在较大的差别,如果你的应用重度使用Oracle系统包,那么迁移工作还是会增加一些工作量的。不过这方面一般还是比较容易解决,通过自行编写一组和Oracle接口兼容的系统包,就可以解决这个问题。只是会增加一定的工作量了。比较麻烦的是dbms_client_info这样的包,Oracle的这个包可以修改会话的信息,如果你的应用中有这方面的需求,那么可能会麻烦一些。
第十三个方面是安全方面的问题,比如透明数据加密、客户端SSL连接服务器等,这些特性并不是所有国产数据库都支持。如果你的应用必须这些特性,那么就会减少可以选择的数据库的种类了。
应用迁移中大家都希望找一个兼容性好的数据库产品,不过兼容性分析是个细活,在分析和选择过程中也会有很多坑。如果你有大量的系统要迁移,那么这项工作还是做得仔细一点为好。上面的十几个点也是今早坐在电脑前临时起意写的,可能有些遗漏,如果有朋友发现还有一些重点的遗漏,请留言告知,我会继续整理一个更为完整的清单。