前言:异库迁移的工具有很多,为了能够快速上手并完成手头的工作,我挑选了两种比较简单实用的方法进行实践操作。
一、整库迁移:使用 mysqldump 迁移 MySQL 到 OceanBase
mysqldump导出的sql中,会有一些特别的语法在OceanBase MYSQL中不支持,需要手动替换掉其中不支持部分。比如说变量 SQL_NOTES,DEFINER,MAX_ROWS 语句等
因此在源端mysql中使用mysqldump导出数据时,分两步走:先导出表结构,再导出表数据。
1.1、mysqldump导出表结构
mysqldump -h 127.0.0.1 -uroot -P3306 -p --compact -d yyc > yyc_ddl.sql
参数说明:
-d, --no-data No row information(不导出表数据)
--compact Give less verbose output(给出更少的详细输出)
查看导出的tpch_ddl.sql中是否有oceanbase不兼容的语句,修改后保存。
1.2、mysqldump导出表数据
mysqldump -h 127.0.0.1 -uroot -P3306 -p -t yyc > yyc_data.sql
参数说明:
-t, --no-create-info Don't write table creation info(不导出表结构)
1.3、向oceanbase中导入表结构和表数据
在导出的表结构语句里,可能包含外键。在导入 OceanBase MySQL 里时,如果外键依赖的表没有创建时,导入脚本会报错。因此导入之前需要将ob中的外键检查约束先禁用掉。
MySQL [oceanbase]> set global foreign_key_checks=off;
MySQL [oceanbase]> show global variables like '%foreign%';
登录到oceanbase中,先导入建表语句tpch_ddl.sql,再导入表数据tpch_data.sql
MySQL [oceanbase]> create database obtest;
MySQL [oceanbase]> use obtest
mySQL [obtest]> warnings; --开启警告提示
--导入表结构
mySQL [obtest]> source /tmp/yyc_ddl.sql
我在导入过程中,出现多次以下报错:
Query OK, 0 rows affected, 1 warning (0.427 sec)
Warning (Code 1286): Unknown storage engine 'InnoDB'
...
ERROR 1273 (HY000) at line 713 in file: '/tmp/yyc_ddl.sql': Unknown collation: 'utf8_unicode_ci'
...
解决方法:修改yyc_ddl.sql然后重新导入即可。
将CHARACTER SET utf8 COLLATE utf8_unicode_ci 改为 CHARACTER SET utf8 COLLATE=utf8_bin 或者去掉;
将ENGINE=InnoDB 去掉。
在vim中可使用命令批量修改 :
%s/CHARACTER SET utf8 COLLATE utf8_unicode_ci//g
%s/ENGINE=InnoDB//g
--导入表数据
MySQL [obtest]> source /tmp/yyc_data.sql
遇到的问题:
导入时有相关报错:
ERROR 1064 (42000) at line 107 in file: '/tmp/yyc_data.sql': You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near '--' at line 1
解决方法:不用处理,不影响正常导入
ERROR 1064 (42000) at line 619 in file: '/tmp/yyc_data.sql': You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'DISABLE KEYS */' at line 1
解决方法:不用处理,不影响正常导入
ERROR 1193 (HY000) at line 905 in file: '/tmp/yyc_data.sql': Unknown system variable 'sql_notes'
原因:变量 SQL_NOTES,DEFINER 语句等 OceanBase MYSQL 会不支持,这里会出现该报错,但不影响数据导入
1.4、数据校验
进入源和目标端数据库,分别查看导出和导入的表总数,检查表中数据行数是否正确,是否有乱码。
MySQL [(none)]> select TABLE_NAME,TABLE_ROWS,TABLE_SCHEMA from information_schema.tables where TABLE_SCHEMA='obtest' order by TABLE_ROWS desc;
+------------------------------+------------+--------------+
| TABLE_NAME | TABLE_ROWS | TABLE_SCHEMA |
+------------------------------+------------+--------------+
| t_sys_permiss_ass | 34352 | obtest |
| t_node_capital_data_config | 20571 | obtest |
...
遇到的问题:当数据迁移至oceanbase中后,oceanbase并不会马上收集表统计信息,因此上面的查询中TABLE_ROWS显示为0或null。需要手动执行合并操作:
$ obclient -h192.168.18.28 -uroot@sys -P2883 -p -A -c
MySQL [(none)]> ALTER SYSTEM MAJOR FREEZE;
Query OK, 0 rows affected (0.138 sec)
MySQL [(none)]> select * from oceanbase.__all_zone where name=‘merge_status’;+—————————-+—————————-+——-+————–+——-+———+
| gmt_create | gmt_modified | zone | name | value | info |
+—————————-+—————————-+——-+————–+——-+———+
| 2022-02-23 14:06:55.527898 | 2022-03-01 17:54:29.960877 | | merge_status | 1 | MERGING |
| 2022-02-23 14:06:55.531006 | 2022-03-01 17:54:31.009331 | zone1 | merge_status | 1 | MERGING |
| 2022-02-23 14:06:55.533115 | 2022-03-01 17:54:31.097070 | zone2 | merge_status | 1 | MERGING |
| 2022-02-23 14:06:55.535227 | 2022-03-01 17:54:31.247850 | zone3 | merge_status | 1 | MERGING |
+—————————-+—————————-+——-+————–+——-+———+
当info显示为IDLE后,即表示统计信息收集完成。
二、表迁移:使用DataX迁移mysql库中的表数据至oceanbase
DataX 是阿里云 DataWorks数据集成的开源版本,在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。DataX 实现了包括 MySQL、Oracle、SqlServer、Postgre、HDFS、Hive、ADS、HBase、TableStore(OTS)、MaxCompute(ODPS)、Hologres、DRDS 、OceanBase 等各种异构数据源之间高效的数据同步功能。
开源地址:https://github.com/alibaba/datax
在开源地址上下载的版本是需要自行编译的,可以在以下链接中下载已经编译好的版本:
http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz
2.1、环境准备
Linux centos7
JDK(1.8以上,推荐1.8)
Python(2或3都可以)
Apache Maven 3.x (Compile DataX)
2.2、DataX工具部署
方法一、直接下载编译好的DataX工具包(推荐)
下载地址:http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz
--此方法需要安装jdk:
yum search openjdk
yum install java-1.8.0-openjdk -y
--将datax.tar.gz解压至本地某个目录,进入bin目录,即可运行同步作业:
$ find ./datax/plugin -name ".*" | xargs rm -f
$ cd ./datax/bin
$ python datax.py <JOB.json>
--自检脚本:
python {YOUR_DATAX_HOME}/bin/datax.py {YOUR_DATAX_HOME}/job/job.json
方法二、下载DataX源码,自己编译
github地址:https://github.com/alibaba/DataX
(1)、使用国内gitee下载DataX源码:
git clone https://gitee.com/mirrors/DataX.git
(2)、安装maven
此步骤会自动安装好jdk,因此不需要额外安装jdk了。
wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
yum -y install apache-maven
(3)、通过maven打包:
cd DataX
mvn -U clean package assembly:assembly -Dmaven.test.skip=true
2.4、配置迁移模板
--查看模板
python ./datax/bin/datax.py -r mysqlreader -w oceanbasev10writer
--生成配置文件
python ./datax/bin/datax.py -r mysqlreader -w oceanbasev10writer > MySQL2OeanBase.json
使用vi等工具编辑MySQL2OeanBase.json
vi MySQL2OeanBase.json
{
"job": {
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"column": ["*"],
"connection": [
{
"jdbcUrl": ["jdbc:mysql://192.168.18.51:3306/yyc?useUnicode=true&characterEncoding=utf8"],
"table": ["t_students"]
}
],
"password": "root123",
"username": "root",
"where": ""
}
},
"writer": {
"name": "oceanbasev10writer",
"parameter": {
"column": ["*"],
"connection": [
{
"jdbcUrl": "||_dsc_ob10_dsc_||obcluster:obmysql||_dsc_ob10_dsc_||jdbc:mysql://192.168.18.28:2883/obtest?useUnicode=true&characterEncoding=utf8",
"table": ["t_students"]
}
],
"obWriteMode": "insert",
"password": "cqiwen",
"username": "cqiwen"
}
}
}
],
"setting": {
"speed": {
"channel": "8"
}
}
}
}
注:此配置为从mysql中读数据,写入到oceanbase数据库。writer为oceanbase,其中的jdbUrl配置格式为:
"jdbcUrl": "||_dsc_ob10_dsc_||集群:租户||_dsc_ob10_dsc_||jdbc:mysql://目标IP:2883/目标库?useUnicode=true&characterEncoding=utf-8"
注意每个填写的值都应有双引号,obWriteMode参数可以有insert、replace等。
遇到的问题:在执行配置文件时提示找不到plugin目录下的某隐藏文件
解决方法:
find ./datax/plugin -name ".*" | xargs rm -f
2.5、将mysql表数据迁移至oceanbase
1)首先要创建好目标库和表结构
因为Datax是迁移工具,并不支持将表结构直接迁移到目标端。所以需要提前在目标端创建库和表。
建议使用mysqldump先将表结构迁移过来,然后使用datax迁移表数据。
由于前面步骤已经使用mysqldump方式将数据迁移至oceanbase中,因此为了测试,我先将t_school表中数据清空:
MySQL [(none)]> truncate table obtest.t_school;
Query OK, 0 rows affected (1.441 sec)
2)迁移表数据
python bin/datax.py job/MySQL2OeanBase.json
......
2022-03-02 15:35:08.725 [job-0] INFO JobContainer - PerfTrace not enable!
2022-03-02 15:35:08.726 [job-0] INFO StandAloneJobContainerCommunicator - Total 17365 records, 1759576 bytes | Speed 171.83KB/s, 1736 records/s | Error 0 records, 0 bytes | All Task WaitWriterTime 2.729s | All Task WaitReaderTime 0.330s | Percentage 100.00%
2022-03-02 15:35:08.727 [job-0] INFO JobContainer -
任务启动时刻 : 2022-03-02 15:34:57
任务结束时刻 : 2022-03-02 15:35:08
任务总计耗时 : 10s
任务平均流量 : 171.83KB/s
记录写入速度 : 1736rec/s
读出记录总数 : 17365
读写失败总数 : 0
2.6、校验数据
MySQL [(none)]> select count(*) from obtest.t_school;
+----------+
| count(*) |
+----------+
| 17365 |
+----------+
1 row in set (0.244 sec)
表中数据又重新导入过来了。
想了解更多干货,可通过下方扫码关注
可扫码添加上智启元官方客服微信👇