一、背景
当前美国对中国的限制越来越多,企业去"IOE"的需求也越来越迫切了,特别是去Oracle数据库。那作为Oracle数据库的替代品,各个企业的选择都不一样,有的使用PostgreSQL,有的使用开源MySQL。但是,为了加强自主可控,一些金融企业开始使用国产数据库,如腾讯云的TDSQL,基于MySQL分支进行开发,完全兼容MySQL,因其高可用性强、数据一致性高、稳定性好,以及腾讯的强大研发能力(避免开源分支闭源带来的风险),TDSQL也是非常多金融企业的首选数据库。
那对于大量使用Oracle数据库的金融企业来说,如何从Oracle迁移到TDSQL,是一个企业必然要面临的问题。
二、迁移方案
2.1 迁移目标
由于TDSQL完全兼容MySQL,迁移方案可参考Oracle到MySQL的迁移。Oracle到MySQL的迁移是一个复杂过程,包含数据库对象迁移和数据库操作代码迁移。由于两个部分涉及的内容都较多,本文主要分享数据库对象中的表迁移。
2.2 Oracle和MySQL数据格式映射关系
进行表迁移前,得了解Oracle和MySQL的数据类型差异,以及它们之间的映射关系,这样才便于解决迁移过程中遇到的问题,同时,对后续的应用开发更有帮助。下图是Oracle官方中介绍的使用 SQL Developer工具进行迁移时,Oracle和MySQL数据类型的映射关系,见https://docs.oracle.com/cd/E12151_01/doc.150/e12155/oracle_mysql_compared.htm#BABHHAJC。
2.3 迁移原理
Oracle到TDSQL迁移表时,主要涉及表结构迁移和表内容迁移。
2.3.1 表结构迁移
在知道了表数据类型的对应关系后,就可以进行表结构迁移了。从Oracle导出表结构定义语句,然后按照对应关系修改数据类型后,在TDSQL中执行建表语句。而此迁移方式,可以手动进行内容修改、也可以通过一些工具进行批量替换数据类型。
2.3.2 表数据迁移
表数据迁移可以在Oracle端进行数据导出,通过各种客户端工具,如Navicat、DBeaver(开源免费)等,进行逻辑导出,得到数据内容的CSV或SQL等文件格式。
然后在TDSQL端,通过mysql的命令行进行导入,如load data、mysql或mysqlsh等工具。建议使用mysqlsh,其可以导入csv文件,并可以通过使用并行提高导入速度。
2.3.2 迁移工具
另外,对于MySQL、PostgreSQL等数据库类型,也可直接通过腾讯云控制台提供的数据迁移的能力,执行对TDSQL的不停机迁移。
除了分步骤迁移外,还有一些集成迁移工具,但其内部原理也基本基于上述思路。常用的集成迁移工具包括Oracle的OGG、开源的KETTLE、商用的Navicat等。
1) OGG的优势是支持异构数据库的迁移、支持数据实时同步且能进行数据回写,但是OGG需要单独配置且配置非常复杂,除非是有实时同步和数据回写的需求,否则不建议使用。
2) KETTLE的优势是开源免费和功能完善,但是其功能还不是很完善,有时一些报错很难看懂,且配置有些复杂,对于一些数据类型简单的Oracle数据库,可以使用此工具。
3) Navicat是一个商业版软件,使用简单,只需通过图形化界面简单配置源端和目标端,即可轻松实现数据迁移。
三、迁移过程
以下是一个完整的基于Navicat的从Oracle迁移到TDSQL的示例。
3.1 源端和目标端介绍
源端为Oracle 11g数据库
在源端Oracle数据库创建测试用表"test".“qy”
CREATE TABLE "test"."qy"
( "id" NUMBER NOT NULL ENABLE,
"name" VARCHAR2(255),
"test" CHAR(10),
"context" LONG,
"age" NUMBER(12,0),
"create_time" TIMESTAMP (6),
"num" CLOB,
"price" FLOAT(2),
PRIMARY KEY ("id")
)
复制
往表里插入测试数据
INSERT INTO "test"."qy" VALUES ('100', 'testname', 'aaaaaaaa ', 'asdfgagasdgasdgasdglkml;wqeijkoiwertghjoqenrgklasndmvlkzsjdfgopasjetfgiowejtgowpijeg ', '99999', TO_TIMESTAMP(' 2022-08-28 19:04:40:000000', 'YYYY-MM-DD HH24:MI:SS:FF6'), 'loblobloblob', '100');
复制
表查询结果如下:
目标端为TDSQL数据库,其中kingdb库下面只有图中8张表。暂时还没有名为qy的表,本次主要就是迁移qy这张表。
3.2 迁移配置
在进行迁移前,需在Navicat客户端上分别连接上源端和目标端数据库,然后配置迁移策略。
3.2.1 连接源端数据库
3.2.2 连接目标端数据库
3.2.3 配置迁移策略
依次点击 工具–》数据传输
源选择连接数据库类型为“oracle”,模式选择要传输的schema,本示例为test用户,可以看到Navicat自动查询出test模式下所有对象,包括本次示例的两张表PRODUCTS和qy。目标直接选择数据库类型为tdsql,要传输的目标database,也就是kingdb。
3.3 迁移数据
点击确定后,即开始迁移。迁移过程中,会先检查目标端表、索引等信息,然后删除重名表,开始传输数据。日志结尾会显示是否成功,成功有Successfully关键字,未成功则有Unsuccessfully关键字。
3.4 迁移校验
3.4.1 表记录校验
在目标端数据库查询,结果的记录数也是1条,数据内容与源端数据内容一致。
3.4.2 表结构校验
首先检查迁移后表结构信息,通过腾讯云数据库管理功能,看到表结构定义如下:
获取表结构定义的DDL语句
CREATE TABLE `qy` (
`id` decimal(65,30) NOT NULL,
`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`test` char(10) COLLATE utf8mb4_general_ci DEFAULT NULL,
`context` longtext COLLATE utf8mb4_general_ci,
`age` decimal(12,0) DEFAULT NULL,
`create_time` datetime(6) DEFAULT NULL,
`num` longtext COLLATE utf8mb4_general_ci,
`price` double DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
复制
通过对比源端和目标端表结构发现,NUMBER转换为decimal,VARCHAR2转换为varchar,CHAR还是CHAR,LONG转换为longtext,TIMESTAMP转换为datetime,CLOB转换为longtext,FLOAT转换为double。数据库类型的转换与SQL Developer的结果一致,符合预期。从这里也可以看到,大多数工具的数据类型转换思路,如果是我们自行通过工具或脚本迁移,这些经验也是值得参考的。
四、迁移总结
4.1 迁移问题总结
本次迁移遇到两个典型问题:
1) 字段类型不一致,无法转换
报错日志:[Err] [Dtf] 1426 - Too-big precision 7 specified for ‘create_time’. Maximum is 6.
报错原因:源端oracle中create_time字段的类型为DATE,在Oracle里其精度为7位,而目标端TDSQL(mysql)的时间类型最多6位,所以无法导入。
解决方案:将Oracle的时间字段修改为timestamp,长度修改为6,保存后即可传输成功。
2) 源端表无主键
报错日志:[Err] [Dtf] 3750 - Unable to create or change a table without a primary key, when the system variable ‘sql_require_primary_key’ is set. Add a primary key to the table or unset this variable to avoid this message. Note that tables without a primary key can cause performance problems in row-based replication, so please consult your DBA before changing this setting.
报错原因:源端oracle中qy表无主键,而目标端TDSQL(mysql)由于开启了sql_require_primary_key参数,要求所有表在创建时有主键,所以导致导入报错。
解决方案:将qy表的id字段修改为主键。
4.2 迁移经验总结
1) 做好多次失败的心理准备
迁移过程由于涉及不同数据库的各个方面的差异,会导致整个过程非常复杂。通常不会一帆风顺,会遇到各种意想不到的情况,所以也会面临多次失败的问题,大家一定要做好充分的心理准备。
2) 弄清原理、胸有成竹
虽然迁移过程艰难,但是只要弄清迁移的原理、数据库的差异并提前做好规划,那么在遇到问题时就可以对症下药、各个击破。