使用OGG从ORACLE到MYSQL的数据同步(二)

作者简介:高文博,OCM,从事ORACLE专业15年,主要服务于各大升级运营商。现任职北京海天起点技术服务股份有限公司山东办事处主任,为山东省内企事业客户提供海量级ORACLE数据库及相关产品的运维支持,参与出版《Oracle云管理平台——企业管理器12c实战指南》一书。

背景:

在本文之前,写过一篇使用了ORACLE GOLDENGATE DIRECT LOAD 数据初始化来进行OGG数据同步的操作文档。在测试过程中没有问题,但在实际生产中,当数据量上升到一定数量级,初始化速度持续下降的,根据测试160万数据到后期每秒初始化仅不到20条,实际测试数据如下:


根据测试数据,1张58万,1张161万的表,实际初始化时间超过15个小时,考虑到上线后如有数据问题等情况需重新初始化,根本不能满足生产要求,因此必须考虑采用其他方式进行初始化。主要思路有3条

  • 使用并行进程,采用多个抽取、复制进程,在进程参数里设置filter条件,将大表分散成若干小表进行初始化
  • 使用第三方工具进行初始化
  • 使用数据库自己的工具将数据导出到文本,再从目标端将文本导入进行初始化

方案测评

首先第一个方案,在其他环境下可以实施,但在当前数据库环境下无法实施,原因主要有两个:

  • 当前源端ORACLE数据库,已有这两张表的抽取进程,并且按照要求只能使用当前抽取进程。
  • 在测试中发现因为在DJ_SMZXX表中SMZXH主键是varchar2(20)类型,根据主键对数据进行过滤,就必须将varchar2进行隐式转换成number类型。在转换过程中遇到了OGG的bug OGG GoldenGate : Numcnv_getnumeric – Buffer Overflow When Using Filter “Where” in a Table Statement (文档 ID 1376606.1)。也就是说当在当前的ogg版本中,数字转换时最大为19位,而SMZXH是20位。该BUG需要到13.1版本才能fix。

因此,第一个方案被放弃,其他场景下该方案应能对初始化的速度有所提升。

其次第二个方案,尝试了PLSQL DEVELOPER/TOAD/NAVICAT/ORACLE TO MYSQL等第三方工具,能进行同步的工具都要求能同时连接源端和目标端两套库,当前网络环境ORACLE和MYSQL数据库分别处于内外网,需要不同的跳板机,无法在一台机器上进行同步;或者这些工具在进行数据导出导入时效率太慢(PLSQL DEVELOPER);而KETTLE作为ETL的主流工具,没有时间深入研究,该方案也只能放弃。

最后是第三个方案,其实也就是使用ORACLE的UTL_FILE包,将表数据导出为文本文件,再从目标端使用mysql的LOAD DATA包,将文本文件导入,经过初步测试,效率非常高,决定使用该方案。

部署OGG for MYSQL

下载介质并安装

http://edelivery.oracle.com选择golden gate for non oracle database11.2.0.1,继续后可以选择for mysql 5.x下载。

将介质上传至服务器指定目录,root用户解压,进入ggsci

配置MYSQL端mgr

源端(ORACLE)配置

查看MANAGER进程

查看源端抽取进程

使用defgen生成表定义文件

异构数据库需使用defgen生成sourcedefs/targetdefs文件

到$GGATE_HOME下使用defgen生成定义文件

./defgen paramfile ./dirprm/defgen.prm NOEXTATTR –//NOEXTATTR,不同版本ogg,不同表结构,需要此参数,11.2版本以后支持此参数

将生成的定义文件复制到目标端

新加一个传送进程

目标端(MYSQL)配置

查看MYSQL数据库字符集

如果字符集不对,导入的中文均未乱码,需要调整字符集。方法如下:

在[mysqld]上面加入下面两句话

在[mysqld]最下面加入下面几句话

然后保存退出

登录后运行

创建表及索引

在正确的字符集下创建支持gbk的innodb表及主键

要创建innodb引擎的表。

要注意ORACLE和MYSQL的对应数据类型。ORACLE中的number对应MYSQL的int,ORACLE中的varchar2对应MYSQL的varchar,建表中需要进行数据类型的转换。

在实际操作中,生产表DJ_NSR_SMZ有一个字段是DJXH NUMBER(20),20位数字,一开始我对应了int,但在mysql中int类型只有10位数字

后来使用bigint也报错,是因为bigint默认19位,一位是符号位,只有在创建表时指定UNSIGNED关键字才能达到20位数字。

测试连接mysql数据库

没有/tmp/mysql.sock,实际位置在/etc/my.cnf里有,是在/var/lib/mysql/mysql.sock

修改后,本地mysql登录有问题,只能创建一个软连接,可以正常连接数据库了。

MYSQL数据库中给root用户赋权

MYSQL端启动Manager

配置GLOBAL

添加一个复制进程

开启传送和复制进程

查看TO ORACLE的传送进程

当前trail文件为c000001,是1号文件,RBA2431

查看MYSQL传送进程

指定从当前文件及块号读取

Mysql传送进程读的trail文件是0号文件,不满足我们的同步需求,因此,需要指定从1号文件2431块开始读取。

源端启动传递进程

MYSQL端启动复制进程

如同步多张表,启动复制进程报错的话,可等同步完再启动。

查看状态

源端

目标端

数据初始化

源端(ORACLE)

使用UTL_FILE包将表数据导出到dj_smzxx.txt。

以上操作导出58万数据不到1分钟

传送dj_smzxx.txt到目标端

目标端(MYSQL)

使用了mysql中的load data工具,其实也就是sqlloader,

运行结果如下:

可以看到,算上显示时间、复制黏贴等一系列时间,总共耗费时间才52秒,效率非常高。但最后输出有18条warning,可实际对比条数没有差别,如对实际数据准确度不放心,可逐条检查。

检查两端OGG进程

源端

目标端

验证

源端(ORACLE)

目标端(MYSQL)

更新

源端(ORACLE)

目标端(MYSQL)

初始化脚本

初始化涉及脚本 (2)

未经允许不得转载:Oracle一体机用户组 » 使用OGG从ORACLE到MYSQL的数据同步(二)

相关推荐