MySQL binlog
为什么有binlog
http://www.jiangxinlingdu.com/mysql/2019/06/07/binlog.html
Mysql 5.0以后,支持通过binary log(二进制日志)以支持主从复制
复制允许将来自一个MySQL数据库服务器(master) 的数据复制到一个或多个其他MySQL数据库服务器(slave),以实现灾难恢复、水平扩展、统计分析、远程数据分发等功能。
binlog应用
主从同步
- 第一步:master在每次准备提交事务完成数据更新前,将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log event,简称event)
- 第二步:slave启动一个I/O线程来读取主库上binary log中的事件,并记录到slave自己的中继日志(relay log)中。
- 第三步:slave还会起动一个SQL线程,该线程从relay log中读取事件并在备库执行,从而实现备库数据的更新。
读写分离
- 有一个主库Master,所有的更新操作都在master上进行
- 同时会有多个Slave,每个Slave都连接到Master上,获取binlog在本地回放,实现数据复制。
- 在应用层面,需要对执行的sql进行判断。所有的更新操作都通过Master(Insert、Update、Delete等),而查询操作(Select等)都在Slave上进行。由于存在多个slave,所以我们可以在slave之间做负载均衡。通常业务都会借助一些数据库中间件,如tddl、sharding-jdbc等来完成读写分离功能。
数据最终一致性
binlog是一把利器,可以保证数据库与与其他任何组件(es、mq、redis等)的最终一致。这是一种优雅的、通用的、无业务入侵的、彻底的解决方案。我们没有必要再单独的研究某一种其他组件如何与数据库保持最终一致,可以通过binlog来实现统一的解决方案。
我们可以进行一些优化,之所以不同场景模拟多个slave来连接master获取同一份binlog,本质上要满足的是:一份binlog数据,同时提供给多个不同业务场景使用,彼此之间互不影响。
消息中间件是一个很好的解决方案。现在很多主流的消息中间件,都支持consumer group的概念,如kafka、rocketmq等。同一个topic中的数据,可以由多个不同consumer group来消费,且不同的consumer group之间是相互隔离的.
binlog事件
binlog文件中存储的内容称之为二进制事件,简称事件。我们的每一个数据库更新操作(Insert、Update、Delete等),都会对应的一个事件。
对支持事务的引擎如innodb而言,必须要提交了事务才会记录binlog。
是用来记录对mysql数据更新或潜在发生更新的SQL语句,并以"事务"的形式保存在磁盘中
binlog记录格式
-
基于SQL语句的复制(statement-based replication,SBR)
记录sql语句在bin log中,Mysql 5.1.4 及之前的版本都是使用的这种复制格式。优点是只需要记录会修改数据的sql语句到binlog中,减少了binlog日质量,节约I/O,提高性能。缺点是在某些情况下,会导致主从节点中数据不一致(比如sleep(),now()等)
-
基于行的复制(row-based replication,RBR)
mysql master将SQL语句分解为基于Row更改的语句并记录在bin log中,也就是只记录哪条数据被修改了,修改成什么样。优点是不会出现某些特定情况下的存储过程、或者函数、或者trigger的调用或者触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是修改table的时候会让日志暴增,同时增加bin log同步时间。也不能通过bin log解析获取执行过的sql语句,只能看到发生的data变更 -
混合模式复制(mixed-based replication,MBR)
是以上两种模式的混合,对于一般的复制使用STATEMENT模式保存到binlog,对于STATEMENT模式无法复制的操作则使用ROW模式来保存,MySQL会根据执行的SQL语句选择日志保存方式。