背景
最近在反对一个从Oracle转TiDB的我的项目,为不便利用端兼容性测试须要把Oracle测试环境的库表构造和数据同步到TiDB中,因为数据量并不大,所以怎么不便怎么来,这里应用CSV导出导入的形式来实现。
整个过程能够分为三个步骤:
- 库表构造转换
- 源数据导出
- 导入指标库
库表构造转换
家喻户晓TiDB是兼容MySQL协定的,所以Oracle的表构造定义在TIDB不肯定能齐全应用,这时候就须要做一些转换,比方字段类型、关键字、零碎函数等等。如果表比拟少的话,手动转一下也不是不行,但本次测试的Oracle其中一个用户下就有将近900张表,手动去转换显然不可能。
这里我应用的工具是TransferDB,它能够反对异构数据Oracle到MySQL/TiDB的构造转换,我的项目主页https://github.com/wentaojin/...。
这个工具由PingCAP某位大佬开发,尽管没有正式对外公布,但的确挺好用的。TransferDB是TiDB运维常用工具集(TiDBA)中的一部分,其余的还蕴含收集统计信息、Mok 解析 key、基于 region key、数据 range、数据估算生成打散语句、查看表数据以及索引 region leader 散布、版本升级,比对 3.0 以及 4.0 配置文件以及 tidb 零碎变量等,能够说是十分实用了,它的我的项目主页是https://github.com/wentaojin/...
应用过Lightning的敌人对这个工具的应用肯定不会生疏,从配置文件到运行程序简直能够说是一模一样,我的项目自带的操作手册也写的十分具体。
它蕴含以下几点外围性能:schema转换、表构造查看、迁徙老本评估、数据迁徙(全量或增量)、CSV导出等,其中有些性能目前还是试验个性,我这里只用到了它的外围个性schema转换。
它的配置文件参数十分丰盛,正文很清晰应用起来非常简单,对于schema转换场景来说,只须要批改[source]
和[target]
局部的连贯信息就行,具体的配置清单能够看这里:https://github.com/wentaojin/transferdb/blob/main/conf/config.toml
配置文件批改好当前,执行上面两条命令就能够实现转换:
# 这个过程是在指标库中生成一个迁徙元信息库,用来存储转换规则、断点信息等等,相似于DM中的dm_meta库./transferdb --config config.toml --mode prepare # 这个过程是实现schema转换,输入sql文件./transferdb --config config.toml --mode reverse
执行成当前会生成2个SQL文件,一个叫 reverse_${sourcedb}.sql
,它是在TiDB中能够执行的sql,另一个是 compatibility_${sourcedb}.sql
,它是TiDB不兼容的sql,比方Foreign Key、Constraint等等,这部分SQL须要人工去评估下应用别的计划来实现。
接着,把reverse_${sourcedb}.sql
导入到TiDB即可,罕用的两种形式:
- mysql -h -u -P < reverse.sql
- source reverse.sql
源数据导出
Oracle数据导出到CSV文件我应用sqluldr2来实现,这是一款在Oracle应用十分宽泛的数据导出工具,它的特点就是玲珑、轻便、速度快、跨平台、反对自定义SQL。
网上的材料比拟多,这里就不具体介绍怎么去应用了,作者(前阿里数据库大佬)也写了一份超级具体的文档,大家搜寻sqluldr2超具体应用教程-loracle数据导出工具及办法
即可。
sqluldr2尽管很弱小,但它却不反对批量导出这点很让人蛊惑,没方法只能另辟蹊径来实现了。
我先把须要导出的表清单放到一个txt文件中:
./sqluldr2linux64.bin user=user/pwd@192.168.1.1:1521/orcl query='select table_name from all_tables where owner='test';' file=/tmp/tidb/sqluldr_tables.sql
再写一个批处理脚本把所有表进行导出:
#!/bin/bashcat /tmp/tidb/sqluldr_tables.sql | while read linedo echo $line /tmp/tidb/sqluldr2linux64.bin user=user/pwd@192.168.1.1:1521/orcl query={$line} charset=UTF8 field=0x7c0x260x7c record=0x3d0x37 null=null file=/tmp/tidb/data/orcltest.{$line}.csvdone
这里有几点须要留神:
- 字段分隔符和换行符倡议应用简单的字符,最好应用多种组合字符(举荐应用ASCII码),这样能尽可能的避免出现导出的数据value count和column count不统一的状况。
- 导出的文件字符集设置成UTF8格局,防止数据导入到TiDB后呈现中文乱码
- 因为前面要应用Lightning导入CSV,文件命名格局要合乎Lightning的要求,即{dbname}.{tablename}.csv
到这里数据就准备就绪了。
导入到TiDB
往TiDB中导入CSV文件有两种罕用的形式,第一种就是Lightning,第二种是Load Data,无论是从操作上还是性能上我都举荐优先思考Lightning,起因如下:
- Load Data只能导入单个文件,Lightning能够批量导入
- Lightning以性能著称,反对多种后端模式,Load Data只能走计算层,还有内存放大景象
- 对于异常情况,Lightning能够断点续传,Load Data要清理数据从新导入
单从900个csv文件来看,Lightning相对是第一抉择。
这里贴一下Lightning的几项外围配置:
[tikv-importer]# 抉择应用的 local 后端backend = "local"# 设置排序的键值对的长期寄存地址,指标门路须要是一个空目录sorted-kv-dir = "/tmp/tidb/lightning_dir"[mydumper]data-source-dir = "/tmp/tidb/data"no-schema = truefilter = ['*.*'][mydumper.csv]# 字段分隔符,反对一个或多个字符,默认值为 ','。separator = '|&|'# 援用定界符,设置为空示意字符串未加引号。delimiter = ''# 行尾定界字符,反对一个或多个字符。设置为空(默认值)示意 "\n"(换行)和 "\r\n" (回车+换行),均示意行尾。terminator = "=%"# CSV 文件是否蕴含表头。# 如果 header = true,将跳过首行。header = false# CSV 文件是否蕴含 NULL。# 如果 not-null = true,CSV 所有列都不能解析为 NULL。not-null = false# 如果 not-null = false(即 CSV 能够蕴含 NULL),# 为以下值的字段将会被解析为 NULL。null = '\N'# 是否对字段内“\“进行本义backslash-escape = true# 如果有行以分隔符结尾,删除尾部分隔符。trim-last-separator = false
注意事项:
- 举荐应用local模式,这样应答blob类型的数据处理更敌对
- 不须要导入表构造,所以设置no-schema = true
- 分隔符和换行符这些要和sqluldr2设置的一样
最初运行Lightning即可:
./tidb-lightning --config tidb.toml --checkrequirements=false
这个过程中我还发现了一个Lightning的bug,前面我会尝试本人修复一下。
其余局部
至于Oracle的其余局部例如存储过程和自定义函数,也不必多想怎么去迁徙了,老老实实改代码去利用端实现。
视图的话我是先用PLSQL把视图导成sql文件再导入TiDB中,然而报错的比拟多,根本都是零碎函数和语法不兼容问题,这部分就波及SQL改写了,没有什么好的方法。
总结
在之前的我的项目中也应用过DSG来实现Oracle到TiDB的数据迁徙,但它毕竟是个纯商业性工具,先充钱能力玩,对于这种测试阶段来说不是太好的抉择。
当然了,官网公布的《TiDB in Action》一书中也给出了Oracle到TiDB的迁徙案例:https://book.tidb.io/session4...,它基于Oracle自家的OGG组件来实现,部署应用上略微有点麻烦。
本文提到的几个工具都是随取随用,不须要装置各种依赖环境,这对于我当初面对的这种没有网络没有yum源的服务器来说几乎太难受了,在这样的小数据量测试场景中不失是一种抉择。
更多好计划也欢送大家举荐,为TiDB生态助力。