前言
由于涉及表结构和数据过多,所以迁移分成表结构迁移,和数据迁移两部分。用到的工具主要是navicat。将问题分块进行统一处理。记录了主键的统一处理、涉及的组件的统一处理。
表结构和数据的迁移对于业务系统来说,结构和数据的迁移工作需要dba的操作。
首先需要
两个开发环境(信创、非信创)开发人员开发以及开发人员功能自测环境。
两个SIT测试环境(信创、非信创)项目功能内测环境。
两个UAT测试环境(信创、非信创)测试团队功能测试环境。
两个准生产环境(信创、非信创)项目组功能测试以及数据准确性验证(生产环境真实数据)。
两个生产环境(信创、非信创)业务人员数据验证。
步骤分为
1.数据库表结构迁移。
2.数据迁移。
3.数据验证以及代码适配。
4.开发测试阶段。
5.项目内部测试阶段(实施以及项目经理测试)。
6.业务人员准生产数据验证。
7.上线以及业务人员生产核对。
数据库表结构迁移
在数据库迁移之前先要看下Oracle版本,和要迁移的信创数据库的版本
--MySQL查询版本 --8.0.24-v24-txsql
select version();
--Oracle查询版本 Oracle 19c
SELECT * FROM v$version;
第一个阶段是在开发环境做表结构的迁移,这个时候可以通过对比两个环境的表的数量来判断表结构是否同步成功。这个阶段会遇到的问题都是两个数据库表结构创建不同导致的。
具体可以分为以下三种情况:
1.Oracle表的主键不是必须的,但是MySQL是必输的(不考虑MySQL隐式主键的情况)。
对于主键分为两种情况,一是有主键但是同步失败,二是没有主键。
第一种Oracle没有主键,那么MySQL就需要创建主键,可以在现有表字段中找一个具有主键属性的字段。具体需要通过业务代码来分析,举一个例子,如果表中某个字段命名是表名_UUID的形式,并且赋值是代码生成的唯一标识,或者是数据库函数SYS_UUID()来赋值的情况,那么可以设定这个字段为主键。这种属于Oracle表是有主键形式的列,但是没有设置主键索引。所以可以直接创建。(如果根据业务逻辑分析出来是需要多个字段,那么同理也可以创建联合索引。)
第二种是Oracle有主键,但是没有迁移成功。这种部分联合主键的表可能会遇到。特殊情况特殊处理。
2.Oracle和MySQL字段类型不统一。大部分是可以通过第三方工具自动转化。转化失败的部分需要特殊情况特殊处理。
3.默认值。对于Oracle和MySQL来说比如主键的默认值就不同,SYS_UUID()和UUID()的区别。再举例,Oracle的date类型字段是可以设置默认值为“”,但是MySQL加了这种默认值会有问题。
这里对于spring boot的组件要做一点特殊说明。部分框架内置了表结构的语句。这里记录两个框架,activity(工作流)和quartz(定时任务)框架。对于activity框架,可以通过修改配置文件。
这里记录一下信创改造过程中Oracle表结构的处理。
注意这里是在开发测试环境进行表结构的修改,修改之前一定要确保有备份!!!!!!
一定要是可以还原到修改之前的备份!!!!!!!
先用单表进行测试!!!!!!!
在开始之前注意清理一些冗余的表,比如备份的数据的表等!!!!!!!!!!
对于同步完的表结构一定要对比下表的数量。然后随机点开几个表确认一下表字段(具体看项目的表数量)。
--oracle 查看有主键的表
select * from user_constraints where constraints_type = 'P'
--oracle 查看表数量
select * from user_tables;
--oracle 查看列数量
select * from user_tab_columns;
--oracle 查看全部列数量
select * from all_tab_columns;
--测试环境表结构处理
--Oracle 对于没有主键的表要先建临时表,再为源表新增主键字段,创建主键索引。在用备份表数据灌入源表中。这样就可以得到一个带着主键的表。
--对于源表中没有主键数据的进行删除
SELECT table name,
'CREATE TABLE '||table_name ||'2024 AS SELECT A.*.GET_UUID TSQL_UUID FROM'|| table_name ||'A:',
'ALTER TABLE'|| table_name ||' ADD TSQL_UUID VARCHAR2(100):',
'INSERT INTO'|| table_name |'SELECT * FROM'|| table_name ||'2024 :',
'Alter TABLE'| table_name ||'ADD CONSTRAINT '||table_name||'_ID PRIMARY KEY(TSQL_UUID):',
'delete '|| table_name || 'where TSQL_UUID IS NULL:',
'DROP TABLE '|| table_name|'2024 ;'
FROM user_tables a
WHERE NOT EXISTS (
SELECT 1 FROM USER_CONSTRAINTS b WHERE b.CONSTRAINT_TYPE ='P' AND b.TABLE_NAME =a.TABLE_NAME);
activity
quartz
对于开源组件最好是用自带的脚本去处理数据迁移!!!!!!
因为经过测试,第三方工具的形式会有问题。比如activity数据迁移的时候blob形式的数据是无法跨库迁移的,会有很多问题,不如重新配置。
在MySQL的表的修改大体是以组件为主,基本都是自动化或者有现成的语句的。
其它的修改基本是字段类型的调整,比如字段精度等。比较分散,没有统一的语句,是按照实际业务情况进行微调,所以没有办法汇总。
因为我的思路是将大块的问题放在Oracle中统一处理。
数据库表数据迁移以及验证
对于数据的迁移,很多时候会发现通过第三方工具同步的部分表的数据同步失败。数据失败的原因可能有很多,表字段类型对字段内容的要求是主要原因。大部分是日期字段格式,数字字段的精度等。比如Oracle数据库的日期默认值“”是同步不到MySQL的。
代码修改
环境弄好以后就是代码的适配了,可以先不换中间件起一下服务。也就是让两个环境只有数据库不一样起一下服务。哪里报错改哪里,改完之后再更新中间件。这样方便定位问题。(也可以一起更换,包括其它组件一起更新都可以,看项目实际情况。)在改的过程中就会遇到函数的改造、语法的修改。
1.函数的问题
函数问题有两种办法,对于常用的函数,比如to_date(),可以用STR_TO_DATE()来替换。也可以在MySQL中创建to_date()函数。可以对常用函数在MySQL中创建对应的同样名称和用法的函数。然后对于不常用的函数,或者同名但是用法不同的函数进行代码的适配。大部分在idea里面可以批量替换。
2.语法问题
语法问题分成增删改查,即insert、delete、update、select。这里面select的问题较多,大部分语法问题都是数据集别名的问题。加一个别名就可以解决,通常是多表的嵌套联查。
一个区别较大的语法是merge into。这个在MySQL中对应的语法是按照主键去处理的,如果Oracle的merge into 的on的条件不是主键,就没法处理了。可以分成一个update和一个insert语句。
中间件适配
tomcat一般是要更换的,我们是换到了东方通。东方通遇到了Java版本的问题和字符集的问题,尽量保证信创和非信创环境的各种组件的版本一致。转换起来就不会有太多的问题。东方通的实际的配置等以项目实际情况为准。
测试阶段以及后续上线
代码的修改工作量不会特别大,但是开发自测的工作量很大。在功能测试阶段要尽可能确保每一个业务场景都测过。(在实际开发过程中会很难,所以在修改完第一版代码之后,比如修改完一个模块的代码后就可以将项目组其它人员、测试团队等动员起来做测试工作,这会节约很多开发时间。在修改测试出问题的同时,再继续修改其它模块。)
功能测试阶段完成之后是数据验证阶段,这需要从生产的Oracle数据库迁移数据到准生产环境(看项目实际情况)。用作数据的验证,需要两个系统每天在同一个界面录入同样的数据,每天验证一遍数据的结果。这个时长具体看项目验收的要求。