OBLogProxy简介
OBLogProxy即OceanBase的增量日志代理服务,它可与OceanBase建立连接并读取增量日志,从而为下游服务提供了变更数据捕获(CDC)的功能。
关于OBLogProxy的详尽介绍与具体的安装指引,您可以参考这篇官方OBLogProxy文档 。
此服务主要具备两种模式,分别为CDC模式与binlog模式。
CDC 模式需结合 OBLogClient 来完成数据订阅,此客户端能够将接收到的 clog 日志数据转换成 LogMessage 对象,用户可以使用它们来定制自己的处理逻辑。鉴于该模式需用户想自行编写一些代码来解析和使用这个相对不那么通用的 LogMessage,因此本次我并未尝试使用它。
binlog 模式会生成和 MySQL 兼容的 binlog,binlog 比上面提到的 LogMessage 要通用的多,下游 MySQL 生态的组件都可以直接消费 binlog。所以我们能够通过这个模式,以很低的成本去复用 MySQL 生态工具,避免重复造轮子,我这次要试用的就是这个模式。
要把 OceanBase 的 clog 转成 binlog 往下游发送,一共分三步:
- 我们首先要有一个标准的 OceanBase 的集群。
- 然后会起一个叫 Binlog Service 的服务,它可以跟每个租户之间建立一个连接,去拉每一个租户的 clog 日志,把 clog 日志拉过来之后,会把它解析成 binlog 文件,然后存储到磁盘上。
- 外部的订阅服务,如果有需求的话,就可以给 Binlog Service 发一个 binlog dump 的命令,Binlog Service就会基于这个 binlog dump 命令的参数,把 binlog 数据往下游去发送。
安装过程
升级 observer 和 proxy 的版本
根据官网上写的 binlog 模式的使用限制,先得升级一下 observer 和 proxy 到比较新的版本。
我这边的 observer 版本是符合要求的,但是 proxy 版本比较老,需要在官网上下载一个最新版本的 proxy 4.2.1,把软件版上传到 ocp,再拿鼠标点一下升级 proxy。
然后等升级任务完成就好了,升级 proxy 大概要花两分钟左右的样子。
安装 OBLogProxy
详见官网链接。看官网的架构图,oblogproxy 需要和 proxy 进行交互,所以我这里直接把 oblogproxy 放到了 proxy 所在的节点上,版本是 2.0.0。
[xiaofeng.lby@obrd.80c.sqlvd-a3-n0 /home/xiaofeng.lby]
$sudo rpm -i oblogproxy-2.0.0-101000012023121819.el7.x86_64.rpm
安装一共分三步:配置 proxy,配置 oblogproxy,运行 oblogproxy。
配置 proxy
这里不求甚解,在安装 oblogproxy 的节点上用 proxy 连接测试集群的 sys 租户,然后直接照着官网链接和洪波博客的步骤把相关的几个配置命令都执行了一遍。
obclient -h11.124.5.45 -P2883 -uroot@proxysys#obn.xiaofeng.lby.11.158.31.20 -Dtest
# 查询 binlog server 地址,当前为空
show proxyconfig like 'binlog_service_ip';
# 配置 binlog service 地址
alter proxyconfig set binlog_service_ip="11.124.5.45:2983";
# 开启 binlog 服务
alter proxyconfig set enable_binlog_service='True';
# 设置 init_sql,开启 show_ddl_in_compat_mode。
# 开启后,OceanBase 的 show create table 输出将完全兼容 MySQL 的语法。
alter proxyconfig set init_sql='set _show_ddl_in_compat_mode = 1;';
# 验证配置是否正确
show proxyconfig like 'binlog_service_ip';
其中有一步是设置 _show_ddl_in_compat_mode 这个东西,感觉挺有意思。官网上说:“OceanBase 的 DDL 语法与 MySQL 的 DDL 语法存在一定的差异,即 OceanBase 具有自己的一些扩展语法,因此部分 DDL 语法可能无法解析。为了解决这种问题,OceanBase 进行了兼容性支持。我们建议在 OBProxy 中设置 init_sql 来开启_show_ddl_in_compat_mode。开启后,OceanBase 的 show create table 输出将完全兼容 MySQL 的语法。”
TODO:不是特别理解官网上的这个说法,一会儿准备试试在 OceanBase 里创建一个 OceanBase 支持,但是 MySQL 不支持的 global index,看看生成的 binlog 结果是啥。
create table t1(c1 int primary key, c2 int, c3 int);
create unique index idx3 on t1(c3) partition by hash(c3);
show create table t1\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL,
`c3` int(11) DEFAULT NULL,
KEY `idx3` (`c3`) BLOCK_SIZE 16384 GLOBAL
partition by hash(c3)
(partition `p0`)
)
配置 oblogproxy
这一步直接参考官网步骤,没遇到啥问题,这里略去不提。
运行 oblogproxy
这一步直接参考官网步骤,也没遇到啥问题,这里也略去不提。成功启动 oblogprxoy 之后,可以看到多了一个叫 binlog_converter 的进程。
[xiaofeng.lby@obrd.80c.sqlvd-a3-n0 /usr/local/oblogproxy]
$ps -ef | grep 'logproxy'
root 70452 131066 12 15:53 pts/7 00:00:51 ./binlog_converter binlog_converter.conf /usr/local/oblogproxy/run/obn.xiaofeng.lby.11.158.31.20/mysql
xiaofen+ 103276 76610 0 16:00 pts/4 00:00:00 grep --color=auto logproxy
root 131066 131059 2 15:39 pts/7 00:00:25 ./bin/logproxy -f ./conf/conf.json
正确性验证
参考了洪波的博客,知道了生成的 MySQL binlog 应该在 /usr/local/oblogproxy/run/cluster_name/tenant_name/data
这个路径下。
[xiaofeng.lby@obrd.80c.sqlvd-a3-n0 /usr/local/oblogproxy/run/obn.xiaofeng.lby.11.158.31.20/mysql/data]
$ls
index.LOCK mysql-bin.000001 mysql-bin.index
因为要求 mysqlbinlog 的版本是 3.4,所以我在 MySQL 官网上下载了一个 5.7.9 版本的 MySQL,准备用这个版本的 MySQL 里自带的 mysqlbinlog 3.4 看下对应的 SQL 能否在原生 MySQL 里执行。
这里鸡蛋里面挑下骨头,回到上面那个 global index 的问题,执行创建全局索引的 DDL,看下生成的 mysql-bin.000001 里面是什么东西,以及能否在 MySQL 下面执行。
在 OceanBase 下面执行这几条 SQL
create table t1(c1 int primary key, c2 int, c3 int);
# 估计这条 DDL 生成的 binlog 在原生 MySQL 里无法成功执行
create unique index idx3 on t1(c3) partition by hash(c3);
insert into t1 values(1, 2, 3);
update t1 set c1 = 2;
delete from t1;
这里也不求甚解直接照着洪波的命令执行。
[xiaofeng.lby@obvos-dev-d3 /home/xiaofeng.lby/work/mysql-5.7.9-linux-glibc2.5-x86_64/bin]
$./mysqlbinlog --no-defaults --base64-output=decode-rows -vv /home/xiaofeng.lby/work/mysql-bin.000001
看到的是下面这个结果:dml 部分的 update 被记录成了 delete + insert,都能对的上;ddl 部分好像有些小问题,OceanBase 里的独有的全局索引 idx3 被记录成了 create unique index idx3 on t1(c3) partition by hash(c3)。
MySQL 里面不支持索引相对于主表有自己独立的分区,create unique index idx3 on t1(c3) partition by hash(c3) 显然是不可能执行成功的。可能需要改成 create unique index idx3 on t1(c3)?不过这样改含义好像变化的有点儿大,可能需要相关的产品同学确定清楚这里的产品行为究竟应该是怎样。
总结
OceanBase 里和 MySQL 兼容的基础功能看上去生成的 binlog 没啥问题,但是 OceanBase 相对于 MySQL 独有的一些扩展功能,例如我测试的全局索引之类的,可能还值得产品同学和研发同学再继续打磨一下。
今天由于时间关系只是做了一个基本的小验证,还没来得及用下游的 canal、flink-cdc 等其他 mysql 生态工具向 proxy 执行 binlog dump 命令去测试,to be continue。