记一次简单的Oracle离线数据迁移至TiDB过程
背景
最近在支持一个从Oracle转TiDB的项目,为方便应用端兼容性测试需要把Oracle测试环境的库表结构和数据同步到TiDB中,由于数据量并不大,所以怎么方便怎么来,这里使用CSV导出导入的方式来实现。
整个过程可以分为三个步骤:
- 库表结构转换
- 源数据导出
- 导入目标库
库表结构转换
众所周知TiDB是兼容MySQL协议的,所以Oracle的表结构定义在TIDB不一定能完全使用,这时候就需要做一些转换,比如字段类型、关键字、系统函数等等。如果表比较少的话,手动转一下也不是不行,但本次测试的Oracle其中一个用户下就有将近900张表,手动去转换显然不可能。
这里我使用的工具是TransferDB,它可以支持异构数据Oracle到MySQL/TiDB的结构转换,项目主页https://github.com/wentaojin/transferdb。
这个工具由PingCAP某位大佬开发,虽然没有正式对外发布,但确实挺好用的。TransferDB是TiDB运维常用工具集(TiDBA)中的一部分,其他的还包含收集统计信息、Mok 解析 key、基于 region key、数据 range、数据估算生成打散语句、查看表数据以及索引 region leader 分布、版本升级,比对 3.0 以及 4.0 配置文件以及 tidb 系统变量等,可以说是非常实用了,它的项目主页是https://github.com/wentaojin/tidba
使用过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/bash
cat /tmp/tidb/sqluldr_tables.sql | while read line
do
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}.csv
done
这里有几点需要注意:
- 字段分隔符和换行符建议使用复杂的字符,最好使用多种组合字符(推荐使用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 = true
filter = ['*.*']
[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/chapter5/from-oracle-to-tidb.html,它基于Oracle自家的OGG组件来实现,部署使用上稍微有点麻烦。
本文提到的几个工具都是随取随用,不需要安装各种依赖环境,这对于我现在面对的这种没有网络没有yum源的服务器来说简直太舒服了,在这样的小数据量测试场景中不失是一种选择。
更多好方案也欢迎大家推荐,为TiDB生态助力。
记一次简单的Oracle离线数据迁移至TiDB过程的更多相关文章
- MS SQL到Oracle的数据迁移笔记
MS SQL到Oracle的数据迁移笔记 一.任务背景 旧系统使用MS SQL Server数据库,新系统使用Oracle数据库,现在需要将旧系统中的数据迁移到新系统中,旧数据按照约定的规则转换后,能 ...
- oracle impdp 数据迁移 至RDS 亚马逊云
背景: 公司年底打算将aws rds11.2.0.4 oracle 数据库升级到19c,所以需要进行升级测试,所以需要我把线上的库数据迁移到一台测试的rds oracle 亚马逊云的数据库中,然后升级 ...
- 从一个简单的Delete删数据场景谈TiDB数据库开发规范的重要性
故事背景 前段时间上线了一个从Oracle迁移到TiDB的项目,某一天应用端反馈有一个诡异的现象,就是有张小表做全表delete的时候执行比较慢,而且有越来越慢的迹象.这个表每次删除的数据不超过20行 ...
- oracle 数据库数据迁移解决方案
大部分系统由于平台和版本的原因,做的是逻辑迁移,少部分做的是物理迁移,接下来把心得与大家分享一下 去年年底做了不少系统的数据迁移,大部分系统由于平台和版本的原因,做的是逻辑迁移,少部分做的是物理迁 ...
- oracle跨平台数据迁移 expdp/impdp 字符集问题 导致ORA-02374 ORA-12899 ORA-02372
环境描述: 源数据库环境: 操作系统:Windows SERVER 2008R2 数据库版本:单实例 ORACLE 11.2.0.1 目标端数据库环境: 操作系统:redhat ...
- SAP HANA SLT 将Oracle表 数据同步到HANA数据库
简单介绍SLT 同步数据的整个配置过程: 在SLT系统中创建与Oracle的链接 在HANA监控平台上,创建Configuration 创建表的同步作业 ——————————————BEGIN———— ...
- 利用Kettle进行SQLServer与Oracle之间的数据迁移实践
Kettle简介 Kettle(网地址为http://kettle.pentaho.org/)是一款国外开源的ETL工具,纯java编写,可以在Windows.Linux.Unix上运行,数据抽取高效 ...
- 记一次oracle 11g数据导入
1.ORACLE数据库数据导入到测试库环境 172.15.1.51 root kic@test 172.15.1.52 root 一般先将数据导入52的环境(配置比较低),再将数据导入51的环境(本 ...
- 【SQLServer】记一次数据迁移-标识重复的简单处理
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 今天在数据迁移的时候因为手贱遇到一个坑爹问题,发来大家乐乐,也传授新手点经验 迁移惯用就 ...
随机推荐
- CF140D New Year Contest 题解
Content 小 G 想打一场跨年比赛,比赛从下午 \(18:00\) 开始一直持续到次日清晨 \(6:00\),一共有 \(n\) 道题目.小 G 在比赛开始之前需要花费 10 分钟考虑这些题目的 ...
- docker查看容器元数据、详细信息,查看容器挂载的目录
通过 docker inspect 175f 查看容器元数据 我们启动docker的时候会挂载目录,但是挂载之后 后面就忘了 如何查看挂载的目录位置呢 可以通过 docker inspect a7a6 ...
- centos使用docker安装mysql5.7
搜索镜像 docker search mysql 拉取镜像 docker pull mysql:5.7 启动mysql镜像 docker run -p 3306:3306 --name mysql - ...
- 【LeetCode】437. Path Sum III 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS + DFS BFS + DFS 日期 题目地 ...
- 【LeetCode】589. N-ary Tree Preorder Traversal 解题报告 (Python&C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...
- 【剑指Offer】二叉搜索树与双向链表 解题报告(Python)
[剑指Offer]二叉搜索树与双向链表 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interview ...
- 在Apache上用mod_wsgi部署Flask (python 3.8, Ubuntu)
因为项目源码用了一些>python3.5的语法糖,但是Ubuntu的mod_wsgi包对应的是python3.5,所以采用从pip安装mod_wsgi的方法 参考: Flask教程 mod_ws ...
- 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)
大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...
- Spring企业级程序设计 • 【第2章 Spring Bean管理进阶】
全部章节 >>>> 本章目录 2.1 bean标签和import标签 2.1.1 标签中的id属性和name属性 2.1.2 Bean的作用范围和生命周期 2.1.2 Be ...
- Browser Events 常用浏览器事件
事件 说明 click 鼠标点击时触发此事件 dblclick 鼠标双击时触发此事件 mousedown 按下鼠标时触发此事件 mouseup 鼠标按下后松开鼠标时触发此事件 mouseover 当鼠 ...