db-cdc之mysql 深入了解并使用binlog

1.什么是binlog?

2.binlog可以用来干什么?

3.怎么样使用binlog?

binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE...)以及表数据修改(INSERT、

UPDATE、DELETE...)的二进制日志。实际落库产生的日志(事务提交后)。

我们先看一下Mysql数据更新的流程:

binlog可以干什么?

• 通过如上所述,我们知道binlog是mysql的已提交日志,是实际落库的,那么如果可以监听到binlog那么我们可以用来处理DB主从同步,跨库同步,数据备份,同步ES,缓存刷新等等

怎么样使用binlog?

准备工作

1.检查binlog是否开启

SHOW GLOBAL VARIABLES LIKE 'log_bin%'; 结果返回不等于ON时代表关闭

可以通过my.ini配置文件(linux中为my.cnf) log-bin=mysql-bin //指定binlog日志文件的名称,可以根据实际需求进行命名。 binlog-format=ROW //设置binlog的格式,下面会解释这三种格式。

2.检查binlog格式

SHOW GLOBAL VARIABLES like ' binlog_format%';

mysql binlog 分为三种模式(STATEMENT,ROW,MIXED)

  • Statement(Statement-Based Replication,SBR):每一条会修改数据的 SQL 都会记录在 binlog 中
  • Row(Row-Based Replication,RBR):不记录 SQL 语句上下文信息,仅保存哪条记录被修改
  • Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合体

这里我们设置Row即可

SET GLOBAL binlog_format = 'ROW';

SET GLOBAL binlog_row_metadata = 'FULL';//8.0版本以下不需要设置

现在准备工作完成,可以开始写代码订阅master节点去获取binlog信息了,再次之前我们先了解下 binlog的存储原理

3.多文件存储

mysql 将数据库更新操作对应的event记录到本地的binlog文件中,显然在一个文件中记录所有的 event是不可能的,过大的文件会给我们的运维带来麻烦,如删除一个大文件,在I/O调度方面会给我们带来不可忽视的资源开销。

因此,目前基本上所有支持本地文件存储的组件,如MQ、Mysql等,都会控制一个文件的大小。在数据量较多的情况下,就分配到多个文件进行存储。

在mysql中可以通过

show binlog events;

得到binlog的log_name(文件名)和大小以及pos(偏移量位置)

这两个会在后面发送dump到master节点去订阅的时候用到,代表从binlog的哪处位置开始订阅,master 就会在EventStream中发送此文件节点之后的所有数据库变更信息

4.Binlog管理事件

所谓binlog管理事件,官方称之为binlog managent events,你可以认为是一些在任何模式下都有可能会出现的事件,不管你的配置binlog_format是Row、Statement还是Mixed。

每个binlog文件总是以Format Description Event 作为开始,以Rotate Event 结束作为结束。如果你使用的是很古老的Mysql版本中,开始事件也有可能是START EVENT V3, 而结束事件是**Stop Event。**在开始和结束之间,穿插着其他各种事件。

在Event_Type列中,我们看到了三个事件类型:

  • **Format_desc:**也就是我们所说的Format Description Event,是binlog文件的第一个事件。在Info列,我们可以看到,其标明了Mysql Server的版本是8.0,Binlog版本是4。
  • **Previous_gtids:**该事件完整名称为,PREVIOUS_GTIDS_LOG_EVENT。熟悉Mysql 基于GTID复制的

同学应该知道,这是表示之前的binlog文件中,已经执行过的GTID。需要我们开启GTID选项,这个事件才会有值,在后文中,将会详细的进行介绍。

  • **Rotate:**Rotate Event是每个binlog文件的结束事件。在Info列中,我们看到了其指定了下一个 binlog文件的名称是mysql-bin.000004。

5.开始发送一个dump到master节点

serverId 代表此slave节点的id(不要跟master节点重复),订阅binlog需要模拟一个slave(从节点)去向master节点发送dump ,后续就会接收的订阅返回的事件流信息 filenameposition 前面提到过的文件名偏移量

发送成功后就会接收到master节点返回的event信息

每个binlog事件都以一个事件头(event header)开始,然后是一个binlog事件类型特定的数据部分,称为事件体(event body)。

事件体的具体结构与事件类型相关,以QUERY_EVENT类型为例,存储格式如下:

常见的事件类型有:

  • FORMAT_DESCRIPTION_EVENT:该部分位于整个文件的头部,每个binlog文件都必定会有唯一一个该event
  • PREVIOUS_GTIDS_EVENT:包含在每个binlog的开头,用于描述所有以前binlog所包含的全部*GTID*的一个集合(包括已经删除的binlog)
  • GTID_EVENT/ANONYMOUS_GTID_EVENT:每一个Query事务前都会有这样的一个GTID_EVENT,如果未开启则是ANONYMOUS_GTID_EVENT。

事务开始时,执行的BEGIN操作;ROW格式中的DDL操作等

  • TABLE_MAP_EVENT:每个DML事务之前,都会有一个TABLE_MAP_EVENT,记录操作对应的表的信息。
  • WRITE_ROW_EVENT:插入操作。
  • DELETE_ROW_EVENT:删除操作。
  • UPDATE_ROW_EVENT:更新操作。记载的是一条记录的完整的变化情况,即从前量变为后量的过程 • XID_EVENT:主要是事务提交的时候回在最后生成一个xid号,有这个便代表事务已经成功提交了
  • ROTATE_EVENT:Binlog结束时的事件,与一样仅有一个

具体的源码可以通过以下链接去下载:

https://github.com/kogel-net/Kogel.Subscribe

尾言

这个轮子是在前两年时候写的,那时候想利用mysql的cdc解决缓存刷新的问题,但是找了一圈发现只有 java开源的轮子例如canal,flinkcdc等,c#社区好像并无此类似轮子就想写一个,完善下c#/.net社区,希望以后.net发展能够越来越好吧。

相关推荐
小技与小术2 小时前
数据库表设计范式
数据库·mysql
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作
运维·服务器·数据库·sql·mysql
安迁岚2 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验九 触发器
数据库·sql·mysql·oracle·实验报告
无敌岩雀2 小时前
MySQL中的索引
数据库·mysql
东阳马生架构3 小时前
MySQL原理简介—1.SQL的执行流程
mysql
安迁岚3 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验六 视图
数据库·sql·mysql·oracle·实验报告
.生产的驴3 小时前
SpringCloud OpenFeign用户转发在请求头中添加用户信息 微服务内部调用
spring boot·后端·spring·spring cloud·微服务·架构
喵叔哟3 小时前
16. 【.NET 8 实战--孢子记账--从单体到微服务】--汇率获取定时器
微服务·oracle·.net
xoxo-Rachel3 小时前
(超级详细!!!)解决“com.mysql.jdbc.Driver is deprecated”警告:详解与优化
java·数据库·mysql
Smile丶凉轩3 小时前
微服务即时通讯系统的实现(服务端)----(1)
c++·git·微服务·github