Springboot-mysqlbinlog 日志监听实践

鸡声茅店月,人迹板桥霜。

1 前言

关于 mysql 的数据同步,一般都是读取 mysql 的 binlog 日志文件,来获取数据的变更进行同步。在开源项目中,监听 mysql binlog 的工具有很多, 比如 mysql-binlog-connector-java、cannal 、flink-cdc , 在本文中会介绍第一个工具 mysql-binlog-connector-java 的用法。它是 github上的一个开源项目, 是二进制日志监听d的利器。

在介绍之前,我们需要先复习一下 mysql 数据同步的知识,如下图所示,mysql 的 master 节点在数据产生变动时,会生成一个 binarylog, slave 节点通过监听来读取 mysql 的日志,通过 io thread 来将读取到的信息转换成 relay log 中继日志,最后通过 sql thread 的操作在 slave 数据库中恢复数据,这就是数据同步的主要流程。

2 mysql 开启 binlog

在使用之前 mysqlbinlog 之前,需要先开启 mysql binlog , 通过命令 show variables like 'log_bin'; 可以查询数据是否已经开启 binlog 日志,在没有开启的情况下,是不能监听数据变动的。

ini 复制代码
mysql 配置文件 my.cnf 中添加以下配置即可开启 binlog
log_bin=mysql-bin
binlog-format=ROW
server-id=1
  • 开启 mysql binlog 时,需要配置 binlog 的日志格式和 server-id, 日志格式分为三种类型,分别是 STATEMENT、ROW、MIXED,在这里需要采用 ROW 模式。
  • server-id 用于标识 sql 语句是来自哪个 server,如果要正常监听事件就需要在配置文件中进行设置 server-id。

3 mysql-binlog 介绍

mysql-binlog 主要是通过监听并解析 mysql binlog,转换成对应的事件来提供给开发者来操作,主要的事件如下所示:

sql 复制代码
RotateEventData  当MySql的binlog 文件发生滚动的时候会发生此事件
FormatDescriptionEventData  格式化显示事件信息,包括 binlog 版本,mysql 版本,事件时间戳,数据长度以及检验方式
QueryEventData   当binlog格式设置的是statement|mixed且做DB有了更新、插入或删除操作的时候会发生改(例如修改Row,alter表等)
TableMapEventData   表映射关系事件, 标识数据库以及数据库表的变动信息。
WriteRowsEventData  表新增数据事件,记录数据库表的新增行信息,可能是多行信息。
UpdateRowsEventData 表更新数据事件,记录数据库表的行更新,可能涉及多个行变动。
DeleteRowsEventData 表删除数据事件,记录数据库表的行删除,删除行的完整信息,会有多行记录。

当有一个变更事件时,首先是 RotateEventData 进行响应,然后是 TableMapEventDataFormatDescriptionEventData 事件,最后才是具体的增删改查事件。一个事件包含有事件头和事件体, 事件头是事件的通用信息,包括事件类型、事件时间、数据长度以及 serverId。事件体即事件的数据信息,不同的事件类型,数据的格式不尽相同。

bash 复制代码
作为 mysql binlog 的日志同步,有下面的优点:
支持解析binlog文件、解析GTID(全局事务id)
支持重连
支持设置故障转移策略
TLS协议安全使用
JMX-friendly
实时监控状态
无第三方依赖

4 环境准备

在开始编码之前,需要引入对应的依赖,

xml 复制代码
<dependency>
    <groupId>com.zendesk</groupId>
    <artifactId>mysql-binlog-connector-java</artifactId>
    <version>0.27.1</version>
</dependency>

另外,在这个过程中,会涉及到数据库表的操作,由于 mysql-binlog 没有展示对应的表字段,所以开发了一个能查询数据库表字段、注释的方法,这里用到了 hutool 工具类,真心很好用,借助这个机会展示一下如何在非web 环境下操作数据库,在操作之前,需要先引入 hutool的依赖和数据库连接驱动的依赖,这两个比较基础,就不在这里贴了。

初始化一个 DruidDataSource, 使用 Db.use 方法即可获取到一个数据库连接。 查询数据库表结构的sql 如下所示:

mysql 复制代码
-- 查询数据库表字段 传入数据库库名和表名即可查询
SELECT COLUMN_NAME as 'name', DATA_TYPE as 'type' , COLUMN_COMMENT as 'comment', ordinal_position as 'srt' 
FROM information_schema.`COLUMNS` 
WHERE TABLE_SCHEMA = 'table_name'  AND TABLE_NAME = 'database_name' order by ordinal_position ;

执行 query 方法,可以查询到一个数据列表,每个实体都对应着一行数据,只需要 get 对应的字段名,即可获取到对应的内容。 最终展示的效果如下图所示:

5 mysql-binlog 实践

终于到了重点部分,首先需要创建一个 BinaryLogClient,需要传入数据库地址,端口账号和密码。

注册监听事件,这里监听的是三个通用的事件,即 RotateEventDataTableMapEventDataFormatDescriptionEventData 事件。

当有数据新增时,会执行数据新增的时间,这里会打印对应的数据库表,以及新增的数据行信息,这里可能会存在多行的数据。

当有数据更新事件时,这里会打印数据变更前后的信息,可以对比比较数据的变动。

当有数据删除时,这里会打印对应的删除信息。

结果展示

sql 复制代码
数据库表信息  103	account	user
插入数据 insert columns {0, 1, 2, 3, 4, 5}
data [12008, 34, 34, 34, null, null]

更新数据 update columns {0, 1, 2, 3, 4, 5}
before -->
[12008, 34, 34, 34, null, null]
after  -->
[12008, 344444, 34, 34, null, null]

删除数据 delete columns {0, 1, 2, 3, 4, 5}
data [12008, 344444, 34, 34, null, null]

6 使用总结

通过以上的演示和总结,了解了 mysql-binlog 的使用方法,并且也介绍了其原理,数据库的变更信息,一直是非常重要的存在,可以结果 hutool 工具类,通过监听数据库表的方式来实现日志信息的记录,这样相比注解的方式更为简单且高效,不影响业务的响应时间。本文中所涉及的代码均已上传至 Git仓库,欢迎大家 stars, 项目 github 地址 springboot-auth

相关推荐
漫步向前17 分钟前
28.mysql读写分离
mysql
CHQIUU1 小时前
告别手动映射:在 Spring Boot 3 中优雅集成 MapStruct
spring boot·后端·状态模式
破 风1 小时前
Docker启动mysql容器时找不到 mysqlx.sock 和 mysqld.sock
mysql·docker·容器
XiaoLeisj2 小时前
【设计模式】深入解析代理模式(委托模式):代理模式思想、静态模式和动态模式定义与区别、静态代理模式代码实现
java·spring boot·后端·spring·设计模式·代理模式·委托模式
李少兄2 小时前
解决Spring Boot版本冲突导致的`NoSuchFieldError`
java·spring boot·后端
Live000002 小时前
Next.js 结合 MySQL 数据库全站开发教程
前端·mysql·next.js
书唐瑞2 小时前
使用 binlog2sql 闪回 MySQL8 数据
mysql·python3·mysql8·binlog2sql·闪回
pwzs2 小时前
常见的 Spring Boot 注解汇总
java·spring boot·后端·spring
他҈姓҈林҈2 小时前
创建可执行 JAR 文件
spring boot
神仙别闹3 小时前
基于Java(JSP)+MySQL实现深度学习的音乐推荐系统
java·深度学习·mysql