我们重点关注红色方框中的那句,是不是有种恍然大悟的赶脚。的确,可以通过解析binlog来实现增量获取变更数据的需求。binlog可以基于binlog filename + binlog position定位唯一一个event,因此只要每次获取数据之后记录此时的binlog filename和binlog position,下次就可以从这个位置开始增量地获取新增的event,基于event就可以解析出变更后的数据。
除此之外,还有一种特殊的业务需求:比如很多电商都对订单价格特别敏感,一旦数据库中的订单价格发生变动,上层应用需要马上得到通知,而不是继续使用cache中的脏数据。这种业务场景就是典型的数据订阅消费,如何实现这种需求呢?
ORACLE数据库的JDBC支持Database Change Notification的功能,可以很方便的支持这种功能需求,可遗憾的是MySQL JDBC却没有这种feature。其实还有一种解决方案,就是使用trigger+Http的方式实现,一旦用户关注的数据发生更新,就会触发自定义的trigger,trigger再将更新后的数据通过HTTP的方式发送给应用方,这种解决方案可以参考开源工具 mysql-udf-http 。是不是很麻烦,而且真心不通用。这个时候纠结了吧,别着急,来看看Binlog。
我们都知道MySQL是基于Binlog实现的主从复制,复制原理见下图:
一旦主上有事务提交,Master就会将事务写到Binlog并发送给Slave,Slave回放接收到的Binlog就可以得到一份和Master完全相同的数据。这也是很多公司实现数据库高可用的基本方案。
那能不能基于此实现数据订阅消费呢? 这里简单介绍一个基于Binlog实现数据订阅消费的开源项目 canal,其核心思想可以简要的概括为:
1. 准备阶段:创建一个进程A模拟Slave的行为,向Master请求Binlog。这样,一旦Master上的数据发生变更,都会马上将Binlog发送给此进程。
2. 订阅阶段:假设应用程序对Product表中的Price字段很敏感,就向A进程订阅Product表Price字段
3. 解析阶段:进程A接收到Master发送过来的Binlog之后对其进行解析,将解析到的数据按照一定形式存储
4. 消费阶段:在解析的过程中一旦发现Product表中的Price字段有变更,就会通知到相应的应用程序
原理是不是很简单,但实际上canal项目还是很复杂,需要模拟MySQL复制协议进行Binlog请求,对Binlog进行解析,实现canal的HA等等,对canal感兴趣的可以移步其主页
总结:MySQL Binlog作为MySQL系统中最重要的日志之一,不仅可以用来实现数据的备份和复制,在增量获取数据库数据、实现数据的订阅&消费这两个领域也是一把锋利的锐器,这篇博文主要是为用户提供一种使用Binlog实现这两种业务的思路和相关可以参考的项目。很显然,无论是哪种业务,归根到底是需要对Binlog进行解析。
本文来自网易实践者社区,经作者范欣欣授权发布。