前几篇文章都是围绕用计算引擎(Spark跟Flink),或者额外的数据导入工具(DataX和Maxwell)来如何读取mysql的测试和验证。
心想,此外还有没有一些常用,或者好用的导mysql数据的办法呢,于是就想到了Doris以及Clickhouse(以下称CK)这两款大家比较常用数据库的外部表方式。
不知道细心的你有没有发现,用CK的 mysql 外部表对其数据导入的尝试,其实在之前的文章中我已经写过了,只不过当时我用的是一个低版本的mysql(5.5)。
可能是因为不能顺利开启它的binlog功能,导致当时尝试用mysql外部表 + 物化视图的方式,是没有办法导入其中的增量数据的(全量数据可以)。
那么这次,通过升级mysql的版本到8.0之后,咱再来看看之前在CK身上的那套玩法是否能奏效,至于Doris如何导入MySQL的增量数据(不依赖外部工具情况下),由于文章篇幅原因,咱下篇再详细展开说。
0. 准备工作
首先准备一个支持binlog功能的mysql数据库,这里下载了较新版本的mysql(8.0.25),默认开启binlog功能。
创建对应的数据源表:
CREATE TABLE `test02` (
`client_ip` varchar(50) NOT NULL,
`domain` varchar(100) NOT NULL,
`time` varchar(20) NOT NULL,
`target_ip` varchar(50) NOT NULL,
`rcode` int NOT NULL,
`query_type` int NOT NULL,
`authority_record` text,
`add_msg` text,
`dns_ip` varchar(50) DEFAULT NULL,
PRIMARY KEY (`client_ip`,`domain`,`time`,`target_ip`,`rcode`,`query_type`)
然后往这张表里灌了一百多万的数据量:

接下来,咱就重点对这张表的存量数据以及增量数据进行导入测试,看看针对高版本的mysql,CK自身所提供的外部表功能,能否胜任对它的CDC操作。
1 CK的mysql外部表
对于CK来说,官方文档提供了专门的mysql外部表功能:

根据文档步骤,既然mysql的目标表已经有了,那么接下来,就是在CK这里创建一张它的映射表,字段类型尽量保持一致(其实没有变):
CREATE TABLE mysql_table01
(
`client_ip` varchar(50) NOT NULL,
`domain` varchar(100) NOT NULL,
`time` varchar(20) NOT NULL,
`target_ip` varchar(50) NOT NULL,
`rcode` int NOT NULL,
`query_type` int NOT NULL,
`authority_record` text,
`add_msg` text,
`dns_ip` varchar(50) DEFAULT NULL
)
ENGINE = MySQL('192.168.221.173', 'test', 'test02', 'xxx', 'xxxx')
建好后,在CK上做个简单的查询:

可以看到,有数据出现,证明映射关系没有问题。
接下来,开始创建一个CK的物化视图,把这个映射表的数据(mysql数据),从mysql真正的给导入到CK本地表中。
CREATE MATERIALIZED VIEW mysql2ck_view01
(
`client_ip` varchar(50) NOT NULL,
`domain` varchar(100) NOT NULL,
`time` varchar(20) NOT NULL,
`target_ip` varchar(50) NOT NULL,
`rcode` int NOT NULL,
`query_type` int NOT NULL,
`authority_record` text,
`add_msg` text,
`dns_ip` varchar(50) DEFAULT NULL
)
ENGINE = MergeTree
ORDER BY client_ip POPULATE AS
SELECT *
FROM mysql_table01
注意,我这里创建时,用到了关键字 POPULATE 意思是我需要导入mysql这张表的所有历史数据。
在创建这个表的过程中,数据其实已经开始在向CK的本地表写入了,看一眼历史数据的导入效果:

发现,这个导入的数据量跟开始查看的mysql表保持一致,代表所有全量历史数据导入成功。
那么接下来,才是激动人心的时刻,当我往mysql数据源表再次插入(新增)数据,看看这边的物化视图能否捕捉到呢?
上次用mysql5.5是没有成功的,现在换成了mysql8,就看它给不给这个面子吧。
我往mysql的源表test02连续新增两条数据后,遗憾的发现,还是跟之前老版本的mysql表现一样,CK这边并不会新增。

mysql新增2条数据

CK数据的量岿然不动
所以,试图通过CK的mysql外部表+物化视图的方式,来实现跟Flink CDC 一样的数据导入功能宣告失败。
那么如果我只想要捕获mysql的增量数据,不要全量数据,是不是可以实现呢?
一番折腾后发现,也不行,反正就是不管怎么着,想通过mysql外部表+物化视图的方式,期待导入mysql的增量数据,就是没门,无关mysql版本问题。
按理说,之前的mysql不行,是因为不支持binlog,但现在换成了mysql8,已经支持binlog了,并且已经通过Flink CDC跟Maxwell两款工具验证过了,居然还是不行(配置之类的确定没有问题),这种油盐不进的货,就很让人生气。
2 CK的 MaterializedMySQL 库引擎
这个是CK推出的同步mysql整库的玩法,同样,在之前的文章中我用mysql5.5 来做测试,没有成功。
看这次换成了mysql8,到底能不能行?
根据官网的要求,需要先在mysql数据库配置中添加开启binlog的配置项,由于mysql8默认开启,所以这里我就直接略过。
接着,就是在CK中创建要同步的mysql的库名:
CREATE DATABASE from_mysql8
ENGINE = MaterializedMySQL('192.168.221.173:3306', 'test', 'xxx', 'xxx')
当然,前提是你必须要在mysql端创建对应的用户,以及对其赋予相关的权限,这里就不赘述。
终于在这一次,行了,可以看到mysql原本的test库下面所有的表,都同步了过来。

mysql的test库下所有表

被同步到CK库from_mysql8下的表
既然能把mysql指定库下面的所有表都能同步过来,那么接下来,我会好奇以下3个地方:
1,同步过来的表数据量是否对的上,如果mysql数据源数据量增加了,这边是否会跟着增加,修改又是否跟着修改;
2,同步过来的表,会采用什么样的引擎,以及对应字段类型是什么样的;
3,同步过来的表数据,是实实在在保存在CK本地了吗?
好,接下来,咱一个个来验证。
首先针对第一个问题,经验证,针对历史全量数据,两边保持一致,而对于增量数据,也可以实时同步,修改的也可以,好评。
针对第二个问题,瞅一眼同步过来的表结构:

发现,它用的去重引擎,而排序字段,跟mysql原表的primary key字段保持一致,并且多了2个额外用来记录当前数据修改情况的字段,
其中_version字段用来记录该条数据update次数,而_sign用来标注该条记录是否被删除。
而至于字段类型,CK也有着自己的一套对应标准,官方文档有详细的说明:

针对第3个问题,看一眼对应的数据目录就知道了,但是从上面的建表语句其实也可以断定(MergeTree家族表),这个表数据就是存在CK本地的。

有对应的目录和数据文件,所以确定是存CK本地无疑。
总结
当把 MySQL 升级到支持 binlog 的更高版本之后,虽然CK提供了mysql外部表 + 物化视图方式,但依然不能实现对其数据的CDC导入,让人比较意外。
但是CK提供的 MaterializedMySQL 引擎库功能,虽然目前还是实验性质的,却可以实现对mysql整个库中表的CDC,如果它能运行稳定,那么确实会给mysql数据的导入带来极大的方便。
那么同样的,在不依靠外力情况下(不借助其他外部软件),CK尚且可以做到如此,那Doris的表现会怎么样呢?
咱下期接着唠...

原文作者:安瑞哥是码农;如有侵权,请联系管理员删除。