本文为墨天轮作者:老王 原创作品
一
背景
二
迁移方案
2.1 迁移目标
2.2 Oracle和MySQL数据格式映射关系
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) 弄清原理、胸有成竹
虽然迁移过程艰难,但是只要弄清迁移的原理、数据库的差异并提前做好规划,那么在遇到问题时就可以对症下药、各个击破。

本文分享自微信公众号 - 墨天轮(enmocs)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。