在发完迁移的123之后,456也总结了一圈,还是那句话,个人经验难免会有偏颇或者不足之处,还请各位多多指正。
数据库概念的映射
什么是概念映射?可以理解为源库和目标库中不同对象类型、不同配置、不同架构之间的对应关系。不同的数据库,难免会有诸多不同之处,既不能生搬硬套,也不能完全不顾。在同构数据库中这个问题可能没有那么突出,一方面官方会给出文档或者指导建议,低版本迁移到高版本的注意事项,另一方面,很多东西的改动也不会特别大。
但是发生在异构数据库之间,这个问题就极其突出了。比如Oracle中的SGA应该对应PG的哪一部分?没有schema这个级别的时候,SQLServer迁到MySQL该怎么做权限和数据的隔离?所以这些工作都需要我们去提前做,可以找过往的项目文档结合自身项目,也可能是手头没有对应文档,全靠自己总结摸索。
大概有如下几个部分需要逐项核对:
- 源库与目标库之间的配置信息映射,比如内存区域的分配规则,Oracle的SGA对应PG的shared_buffers,PGA对应work_mem
- 文件类型的映射信息,例如如wal日志对应redo日志,spfile对应postgresql.conf
- 各个逻辑层级的概念,以及数据隔离,例如Oracle12c之后的pdb——schema——table与PG的database——schema——table的对应关系,以及彼此之间的数据隔离
- 高可用的映射关系,例如如果当前我用的是Oracle RAC,如何选择MySQL类似的高可用方案,如果我使用了SQLServer的AlwaysOn,该使用PG的哪种复制
这些实际上是从迁移之前就要开始做,是一个很细致的东西,既要对源库和目标库的架构对比有所了解,又要对业务系统的资源使用有一定认知,通常不会是DBA独立工作,很可能是与系统项目经理共同完成。
数据类型的转换
不同数据库之间的数据类型是很难有一个一一对应关系的。而在数据库迁移之前,这些对应关系却又是DBA必须要关注的内容。原因有二:
- 不同数据类型的性能存在着很大差异。例如Oracle没有严格意义的int类型,都是以定点数的方式保存,如果迁移到MySQL时,就必须要将整型和定点数分别迁移到MySQL的几种int与decimal中,才能确保不会出现大量int计算被用作decimal带来的性能问题。
- 不是每种数据类型都能找到对应类型或者同等精度的类型。比如说PG里面特有的GIS与几何类型,其他关系型数据库没有能够匹配的,而Oracle当中的日期类型只有一个date,怎么拆分到MySQL里的date/datetime/timestamp,有时候也许仔细权衡
所以在迁移之前,我建议将源库与目标库的所有对象类型都做一个表格,逐一匹配,注明哪些可以平替,哪些需要转换。有些类型甚至可能没法转换,这就意味着需要用其他方式绕过去,甚至更换目标库的软件与版本。不是盲目看XX系统能从XX数据库迁移到XX数据库,就思维定式地认为其他系统也可以。
而且很可能在两边表结构都定好了,仍然出现个别数据无法顺利导入的情况,要么调整表结构和类型,要么将数据采用其他方式处理,甚至还要动一些业务逻辑来适配,实际上花在这个阶段的时间可能比想象的要长。
数据库对象的比对
数据库对象,广义上除了我们常见的表、视图、函数、存储过程、包、dblink,可能还包括一些角色与权限相关内容。这一部分不仅仅涉及到技术,还和业务逻辑深度绑定,即便使用各种改写工具,也需要逐一对照,我建议做如下几个工作:
- 判断目标库与源库之间,各类数据库对象的支持情况,不仅仅是目标库是否支持,如果不支持,该如何改代码或者改SQL来调整
- 逐个自定义函数与存储过程按照业务逻辑重写,如果目标库的函数与存储过程性能比起源库有很大差异,建议重新调整业务逻辑
- 和事务相关的隔离级别、事务模型、自增逻辑、约束、分区等等,这些关系到以后数据计算的结果与性能,需要实际跑一遍业务逻辑来验证
- 系统函数与变量,个别数据库中的系统函数可能无法在其他数据库中找到等效的内容,如果又是业务必需内容,一定要想办法实现这部分
- 权限与对象,不同数据库之间的授权与对象各有各的特点,例如Oracle语境下,user和schema经常是等价的,到了PG又变成了以Role为核心概念的体系
这部分是我经历过的异构数据库中比较头疼的部分,因为和业务逻辑以及计算结果绑定太紧密了,不同数据库之间的语法语义又有着诸多不同。经常看起来差不多的东西,跑出来结果大相径庭,有的甚至在上线之后才发现。所以务必要逐个排查,既有DBA侧的,又有应用程序侧的。
总结一下,准备工作主要是面向两种数据库之间自有内容的差异。无论一个数据库声称自己兼容另一个数据库有多好,除非是代码级别的复制粘贴,否则都只是在尽可能扮演那个数据库,而不是真正的目标数据库。准备充分,才能让后面迁移更加平顺。




