背景介绍
我们都知道,很多用户并不是一开始就是使用 OceanBase 的。所以在他们决定使用 OceanBase 的时候,一定要把之前的业务数据迁移到 OceanBase 上来。如果是全量数据迁移,可以借助离线数据同步工具 DataX 。但是,如果在全量迁移过程中业务产生了新数据,这些新数据又如何迁移呢?此时就需要对数据进行增量迁移。这也是本文的主题:如果使用数据同步工具 Canal 实时把数据从 MySQL 同步到 OceanBase 。
【特别说明】这个教程使用的都是单机部署,只能用来演示。生产环境多为分布式集群部署。Canal 的部署也是支持集群的,需要配合 ZooKeeper 进行集群管理。
P.S. 配合视频教程一起食用效果更佳噢~~视频教程,点击 OceanBase 监控工具 OceanBaseAgent
Canal 介绍
那么什么是 Canal 呢?官方给出的解释, Canal 是个数据同步工具,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。基于日志增量订阅和消费,Canal 有以下功能:
数据库镜像
数据库实时备份
索引构建和实时维护(拆分异构索引、倒排索引等)
业务 cache 刷新
带业务逻辑的增量数据处理
忽略官方的解释,通俗来说, Canal 就是一个数据同步工具。它能让 MySQL 和 OceanBase 建立联系,你在 MySQL 上进行的 DDL 、DML 操作,都能同步到 OceanBase 上。当然前提是 SQL 是两个数据库都支持的语法。
Canal 工作原理
MySQL master 将数据变更写入二进制日志( binary log , 其中记录叫做二进制日志事件 binary log events ,可以通过 show binlog events 进行查看)
MySQL slave 将 master 的 binary log events 拷贝到它的中继日志( relay log )
MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
canal 解析 binary log 对象(原始为 byte 流)
以上内容部分摘自 Canal 官方 GitHub 仓库,更多信息,查看 Canal GitHub 仓库 。
操作步骤
从 MySQL 增量同步数据到 OceanBase 总共分 3 步:
第 1 步,设置 MySQL
第 2 步,部署 Canal
第 3 步,写一些数据,测试实时同步功能
接下来我们按照上述步骤,来一起试一把数据同步。
第 1 步:设置 MySQL
MySQL 的安装本文就不介绍了,比较简单,网上也有很多教程。对于自建 MySQL ,需要先开启 Binlog 写入功能,打开 my.cnf 配置文件:
# 打开配置文件
vim /etc/my.cnf
添加这些配置:
[mysqld]
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
更改配置之后需要重启 MySQL 新的配置才能生效。连接 MySQL ,查看是否生效:
mysql -uroot -p
可以看到此时 log_bin 已经打开,并且 binlog_format 的值为 ROW 。
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
现在创建 Canal 用户:
# 创建 Canal 用户
CREATE USER canal IDENTIFIED BY 'Canal123';
这里说一个我踩的坑,在设置密码时,如果不满足当前密码强度规则,会报错:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
我们看看当前密码强度规则:
SHOW VARIABLES LIKE 'validate_password%';
密码包括 1 个特殊字符,按照要求重置密码,成功
CREATE USER canal IDENTIFIED BY 'Canal@123';
Query OK, 0 rows affected (0.00 sec)
# 现在为 canal 用户授权,*.* 表示所有库
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
-- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
FLUSH PRIVILEGES;
第 2 步:部署 Canal
本文使用的 Canal 是 OceanBase 的定制版本,详细信息,参考 Canal for OceanBase。
部署 Canal Deployer
Canal Deployer 是 Canal 的 server 端,它用来进行 binlog 到 CanalEntry 的转换。来到 Canal for OceanBase 仓库的 Rlease 页面,下载 Deployer 的安装包。然后创建解压目录并解压:
mkdir /tmp/canal2
tar zxvf canal.deployer-$version.tar.gz -C /tmp/canal2
来到安装目录,查看目录结构:
cd /tmp/canal
ls
bin :canal启动、重启、停止文件
conf :canal配置文件
lib :canal运行所需的jar包,注意数据库驱动包版本,可手动更换
logs :canal运行日志
plugin :一些扩展包,如消息队列
修改实例属性配置文件
vi conf/example/instance.properties
这里只介绍我用到的配置,我们把用户名、密码改了就行
# username/password
canal.instance.dbUsername=canal
canal.instance.dbPassword=Canal@123
启动 Canal:
sh bin/startup.sh
注意 Canal 启动需要安装 JAVA JDK,安装命令如下:
yum install java-1.8.0-openjdk* -y
生产环境建议用二进制包装,这样不会影响其他用户。解压以后配置环境变量就可以了。
现在查看日志,看看 Canal 有没有启动成功:
vi logs/canal/canal.log
# 查看 Canal 实例的日志
vi logs/example/example.log
通过日志,我们看到已经启动成功,接下来我们部署 Canal Adaptor。
部署 Canal Adaptor
Canal Adapter 是 Canal 的客户端适配器,它用来解析 CanalEntry 并将增量变动同步到目的端。还是从刚才提到的 Release 页面,下载对应的包,解压方式同上。我们直接来到安装目录,修改启动器配置文件,还是只介绍我用到的配置:
vim conf/application.yml
canalAdapters:- instance: example # canal instance Name or mq topic namegroups:- groupId: g1outerAdapters:- name: logger- name: rdb # 指定为 rdb 类型同步key: mysql1 # 指定 adapter 的唯一 key, 与表映射配置中 outerAdapterKey 对应properties:jdbc.driverClassName: com.mysql.jdbc.Driverjdbc.url: jdbc:mysql://127.0.0.1:2881/amber?useUnicode=true #这里amber是待同步的database名称jdbc.username: root@amber_babe # jdbc username,ob的用户@业务租户,创建业务租户我就不演示了jdbc.password: root # jdbc password ob业务租户密码
默认的配置是注释的,我们需要打开。由于社区版 OceanBase 完全兼容 MySQL 协议,因此在使用时,将其视为 MySQL 配置即可。Adapter 服务在启动时,会加载对应类型 Adapter 配置目录(此处即conf/rdb/)下的所有配置文件。表映射有两种配置形式:按表映射同步和整库同步。我们直接同步数据库镜像,因为生产环境往往有多个表需要同步,修改 RDB 表映射文件有点麻烦。
vim conf/rdb/mytest_user.yml
## Mirror schema synchronize config
dataSourceKey: defaultDS
destination: example
groupId: g1
outerAdapterKey: mysql1
concurrent: true
dbMapping:mirrorDb: truedatabase: amber # 只改这个,需要源库、目标库一模一样
第 3 步:同步数据
创建 database 和 table 我就不演示了,我们直接测试数据同步:
打开一个新的窗口,把日志打印出来,这样方便在插入数据时看到日志的变化。
tail -f x.log
可以看到,左侧插入的数据
mysql> insert into amber1 values (7,8);
已经同步过来了,详情见屏幕右侧的日志。此时,你也可以连接到 OceanBase ,确认数据是不是真的同步过来了。
写在最后
最后,来个小彩蛋, canal 的正确读法是 [kə'næl] ,是运河的意思,比如著名的 Panama Canal(巴拿马运河)。我发现很多小伙伴会读成 ['kænəl] ,记住是 [kə'næl] 哦,重音在后面啦~~