ClickHouse的 MaterializeMySQL引擎
1 概述
MySQL 的用户群体很大,为了能够增强数据的实时性,很多解决方案会利用 binlog 将数据写入到 ClickHouse。为了能够监听 binlog 事件,我们需要用到类似 canal 这样的第三方中间件,这无疑增加了系统的复杂度。
ClickHouse 20.8.2.3版本新增加了 MaterializeMySQL 的 database 引擎,该 database 能映射到 MySQL 中的某个 database,并自动在 ClickHouse 中创建对应的 ReplacingMergeTree。ClickHouse服务做为MySQL副本,读取Binlog并执行DDL和DML请求,实现了基于MySQL Binlog机制的业务数据库实时同步功能。
1.1 特点
(1)MaterializeMySQL 同时支持全量和增量同步,在 database 创建之初会全量同步 MySQL 中的表和数据,之后则会通过 binlog 进行增量同步。
(2)MaterializeMySQL database 为其所创建的每张 ReplacingMergeTree 自动增加了 _sign 和 _version 字段。
其中, _version 用作 ReplacingMergeTree 的 ver 版本参数,每当监听到 insert、update 和 delete 事件时,在 databse 内全局自增。而 _sign 则用于标记是否被删除,取值 1 或者 -1。
目前 MaterializeMySQL 支持如下几种 binlog 事件:
- MYSQL_WRITE_ROWS_EVENT: _sign = 1,_version ++
- MYSQL_DELETE_ROWS_EVENT: _sign = -1,_version ++
- MYSQL_UPDATE_ROWS_EVENT: 新数据 _sign = 1
- MYSQL_QUERY_EVENT: 支持 CREATE TABLE 、DROP TABLE 、RENAME TABLE等。
1.2 使用细则
(1)DDL查询
MySQL DDL查询被转换成相应的ClickHouse DDL查询(ALTER, CREATE, DROP, RENAME)。如果ClickHouse不能解析某些DDL查询,该查询将被忽略。
(2)数据复制
MaterializeMySQL不支持直接插入、删除和更新查询,而是将DDL语句进行相应转换:
MySQL INSERT查询被转换为INSERT with _sign=1。
MySQL DELETE查询被转换为INSERT with _sign=-1。
MySQL UPDATE查询被转换成INSERT with _sign=1和INSERT with _sign=-1。
(3)SELECT查询
如果在SELECT查询中没有指定_version,则使用FINAL修饰符,返回_version的最大值对应的数据,即最新版本的数据。
如果在SELECT查询中没有指定_sign,则默认使用WHERE _sign=1,即返回未删除状态(_sign=1)的数据。
(4)索引转换
ClickHouse数据库表会自动将MySQL主键和索引子句转换为ORDER BY元组。
ClickHouse只有一个物理顺序,由ORDER BY子句决定。如果需要创建新的物理顺序,请使用物化视图。
2 案例实操
2.1 MySQL开启binlog和GTID模式
(1)确保 MySQL 开启了 binlog 功能,且格式为 ROW
打开/etc/my.cnf,在[mysqld]下添加:
server-id=1
log-bin=mysql-bin
binlog_format=ROW
(2)开启GTID模式
如果如果clickhouse使用的是20.8 prestable之后发布的版本,那么MySQL还需要配置开启GTID模式, 这种方式在mysql主从模式下可以确保数据同步的一致性(主从切换时)。
gtid-mode=on
enforce-gtid-consistency=1 # 设置为主从强一致性
log-slave-updates=1 # 记录日志
GTID 是 MySQL 复制增强版,从 MySQL 5.6 版本开始支持,目前已经是 MySQL 主流复制模式。它为每个 event 分配一个全局唯一ID和序号,我们可以不用关心 MySQL 集群主从拓扑结构,直接告知 MySQL 这个 GTID 即可。
(3)重启MySQL
sudo systemctl restart mysqld
2.2 准备MySQL表和数据
(1)在 MySQL 中创建数据表并写入数据
CREATE DATABASE testck;CREATE TABLE `testck`.`t_organization` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` int NOT NULL,
`name` text DEFAULT NULL,
`updatetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY (`code`)
) ENGINE=InnoDB;INSERT INTO testck.t_organization (code, name,updatetime) VALUES(1000,'Realinsight',NOW());
INSERT INTO testck.t_organization (code, name,updatetime)
VALUES(1001, 'Realindex',NOW());
INSERT INTO testck.t_organization (code, name,updatetime) VALUES(1002,'EDT',NOW());
(2)创建第二张表
CREATE TABLE `testck`.`t_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int,PRIMARY KEY (`id`)
) ENGINE=InnoDB;INSERT INTO testck.t_user (code) VALUES(1);
2.3 开启ClickHouse物化引擎
set allow_experimental_database_materialize_mysql=1;
2.4 创建复制管道
(1)ClickHouse中创建 MaterializeMySQL 数据库
CREATE DATABASE test_binlog ENGINE = MaterializeMySQL('hadoop1:3306','testck','root','000000');
其中 4 个参数分别是 MySQL地址、databse、username 和 password。
(2)查看ClickHouse的数据
use test_binlog;
show tables;
select * from t_organization;
select * from t_user;
2.5 修改数据
(1)在 MySQL 中修改数据:
update t_organization set name = CONCAT(name,'-v1') where id = 1
(2)查看clickhouse日志可以看到binlog监听事件,查询clickhouse
select * from t_organization;
2.6 删除数据
(1)MySQL删除数据:
DELETE FROM t_organization where id = 2;
(2)ClicKHouse,日志有 DeleteRows 的 binlog 监听事件,查看数据:
select * from t_organization;
(3)在刚才的查询中增加 _sign 和 _version 虚拟字段
select *,_sign,_version from t_organization order by _sign desc,_version desc;

在查询时,对于已经被删除的数据,_sign=-1,ClickHouse 会自动重写 SQL,将 _sign = -1 的数据过滤掉;
对于修改的数据,则自动重写 SQL,为其增加 FINAL 修饰符。
select * from t_organization
等同于
select * from t_organization final where _sign = 1
2.7 删除表
(1)在mysql执行删除表
drop table t_user;
(2)此时在clickhouse处会同步删除对应表,如果查询会报错
show tables;
select * from t_user;
DB::Exception: Table scene_mms.scene doesn't exist..
(3)mysql新建表,clickhouse可以查询到
CREATE TABLE `testck`.`t_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`code` int,PRIMARY KEY (`id`)
) ENGINE=InnoDB;INSERT INTO testck.t_user (code) VALUES(1);#ClickHouse查询
show tables;
select * from t_user;
相关文章:
ClickHouse的 MaterializeMySQL引擎
1 概述 MySQL 的用户群体很大,为了能够增强数据的实时性,很多解决方案会利用 binlog 将数据写入到 ClickHouse。为了能够监听 binlog 事件,我们需要用到类似 canal 这样的第三方中间件,这无疑增加了系统的复杂度。 ClickHouse 20.…...
Ubuntu 22.04安装Rust编译环境并且测试
我参考的博客是《Rust使用国内Crates 源、 rustup源 |字节跳动新的 Rust 镜像源以及安装rust》 lsb_release -r看到操作系统版本是22.04,uname -r看到内核版本是uname -r。 sudo apt install -y gcc先安装gcc,要是结果给我的一样的话,那么就是安装好了…...
制作Go程序的Docker容器(以及容器和主机的网络问题)
今天突然遇到需要将 Go 程序制作成 Docker 的需求,所以进行了一些研究。方法很简单,但是官方文档和教程有些需要注意的地方,所以写本文进行记录。 源程序 首先介绍一下示例程序,示例程序是一个 HTTP 服务器,会显示si…...
mysql清除数据痕迹_MySQL使用痕迹清理~/.mysql_history - milantgh
mysql会给出我们最近执行的SQL命令和脚本;同linux command保存在~/.bash_history一样,你用mysql连接MySQL server的所有操作也会被记录到~/.mysql_history文件中,这样就会有很大的安全风险了,如添加MySQL用户的sql也同样会被明文记…...
PDF控件Spire.PDF for .NET【转换】演示:自定义宽度、高度将 PDF 转 SVG
我们在上一篇文章中演示了如何将 PDF 页面转换为 SVG 文件格式。本指南向您展示如何使用最新版本的 Spire.PDF 以及 C# 和 VB.NET 指定输出文件的宽度和高度。 Spire.Doc 是一款专门对 Word 文档进行操作的 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻…...
01背包 P1507 NASA的食物计划
P1507 NASA的食物计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 普通01背包状态表示:f(i, j)表示前i件物品放入一个容量为j的背包可以获得的最大价值。 本题类似,f(i, j, k)表示前i件物品放入一个限制为j,且另一个限制为k的背包中可以…...
平衡二叉树c语言版
一、定义二叉树结点结构体 /*** 定义平衡二叉树结点 */ struct avlbinarytree { //数据域NodeData* data;///树高int h;struct avlbinarytree* left;struct avlbinarytree* right; }; typedef struct avlbinarytree AVLNode; 二、声明函数的操作 /*** 创建结点 */ AV…...
初始环境配置
目录 一、JDK1、简介2、配置步骤 二、Redis1、简介2、配置步骤 三、MySQL1、简介2、配置步骤 四、Git1、简介2、配置步骤 五、NodeJS1、简介2、配置步骤 六、Maven1、简介2、配置步骤 七、Tomcat1、简介2、配置步骤 一、JDK 1、简介 JDK 是 Oracle 提供的 Java 开发工具包&…...
记GitLab服务器迁移后SSH访问无法生效的问题解决过程
公司IT心血来潮对GitLab服务器进行安全升级,升级后无法启动。。。只得启用备用服务器,具体的备份机制不祥,只知道原数据都在,但文件系统是否完全一样不清楚。切换为备用服务器后使用SSH下载代码死活不成功,反复提示需要…...
【NGINX--2】高性能负载均衡
1、HTTP 负载均衡 将负载分发到两台或多台 HTTP 服务器。 在 NGINX 的 HTTP 模块内使用 upstream 代码块对 HTTP 服务器实施负载均衡: upstream backend {server 10.10.12.45:80 weight1;server app.example.com:80 weight2;server spare.example.com:80 backup; …...
Android studio run 手机或者模拟器安装失败,但是生成了debug.apk
错误信息如下:Error Installation did not succeed. The application could not be installed:List of apks 出现中文乱码; 我首先尝试了打包,能正常安装,再次尝试了debug的安装包,也正常安装࿱…...
【面试经典150 | 数学】加一
文章目录 写在前面Tag题目来源解题思路方法一:加一 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法,两到三天更新一篇文章,欢迎催更…… 专栏内容以分析题目为主,并附带一些对于本题涉及到的数据结…...
Rust unix domain socket
先用起来再说 use std::io::prelude::*; use std::os::unix::net::UnixStream;fn main() {let mut stream: UnixStream;let mut buffer vec![0u8; 4096];match UnixStream::connect("/tmp/hello.world.serv") {Ok(handle) > {stream handle;match stream.write_…...
初识分布式键值对存储etcd
欢迎大家到我的博客浏览。胤凯 (oyto.github.io)大家好,今天我带大家来学习一下 etcd。 一、什么是 etcd etcd 是一个开源的分布式键值存储系统,主要用于构建分布式系统中那点服务发现、配置管理、分布式锁等场景。它采用 Raft 一致性算法来确保所有节…...
docker swarm集群部署
文章目录 前言一、安装docker1.1 解压1.2 配置docker 存储目录和dns1.3 添加docker.service文件1.4 docker 启动验证 二、docker swarm 集群配置2.1 关闭selinux2.2 设置主机名称并加入/etc/hosts2.3 修改各个服务器名称(uname -a 进行验证)2.4 初始化sw…...
MySQL进阶_9.事务基础知识
文章目录 第一节、数据库事务概述1.1、基本概念1.2、事务的ACID特性 第二节、如何使用事务 第一节、数据库事务概述 1.1、基本概念 事务 一组逻辑操作单元,使数据从一种状态变换到另一种状态。事务处理的原则 保证所有事务都作为 一个工作单元 来执行,…...
IDEA调用接口超时,但Postman可成功调用接口
📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试」资…...
TableUtilCache:针对CSV表格进行的缓存
TableUtilCache:针对CSV表格进行的缓存 文件结构 首先来看下CSV文件的结构,如下图: 第一行是字段类型,第二行是字段名字;再往下是数据。每个元素之间都是使用逗号分隔。 看一下缓存里面存储所有表数据的字段 如下图ÿ…...
java源码-工程讲解
说明: 源码工程目录讲解部分,讲解过程会让大家对后端源码工程有一个大致的了解,能让大家在此改造,就可以衍生出一些新的功能,需要对java技术深入了解,需要看后续java技术讲解部分,源码也是以前很…...
K8S基础笔记
1、namespace 名称空间用来对集群资源进行隔离划分,默认只隔离资源,不隔离网络k8s默认的名称空间为default 查看k8s的所有命名空间 kubectl get namespace 或者 kubectl get ns 创建名称空间 kubectl create ns 名称 或使用yaml方式 编写yamlkub…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
