MySQL:binlog到底是个什么东西

MySQL binlog到底是什么东西?

redolog VS binlog

redo log是一种偏向物理性质的重做日志,因为它里面记录的是类似这样的东西:“对哪个数据页中的什么记录,做了个什么修改”

而redo log本身是属于InnoDB存储引擎特有的一个东西。

而binlog叫做归档日志,它里面记录的是偏向逻辑性的日志,类似于“对users表中的id=10的一行数据做了更新操作,更新之后的值是什么”

binlog不是InnoDB存储引擎特有的日志文件,是属于mysql server自己的日志文件。

提交事务的时候,同时会写入binlog

在提交事务的时候,(策略不为0时)会把redo log日志写入到磁盘文件中去,同时也会把证词更新对应的binlog日志写入到磁盘文件中去。

MySQL:binlog到底是个什么东西
从上面可以看出,执行器负责跟InnoDB交互,包括从磁盘加载数据到Buffer Pool中进行缓存、写入undo日志、更新Buffer Pool里的数据、写入redo log buffer、redo log刷入磁盘、写binlog等等。

实际上,执行器是非常核心的一个组件,负责跟存储引擎配合完成一个SQL语句在磁盘与内存层面的全部数据更新操作。

一个更新语句的执行,大致可以分为两个阶段,上图中的1、2、3、4几个步骤,本质是你执行这个更新语句的时候干的事情。5、6是你提交事务开始的,属于提交事务的阶段了。

binlog日志的刷盘分析

对于binlog日志,有一个sync_binlog参数可以控制binlog的刷盘策略

(1)默认值为0:

  • 当你把binlog写入磁盘的时候,会进入os cache内存缓存
  • 如果此时机器宕机,那么os cache里的binlog日志会丢失

MySQL:binlog到底是个什么东西

(2)当把sync_binlog参数设置为1时:

  • 当提交事务时,会强制把binlog直接写入到磁盘文件中去
  • 这样提交事务之后,哪怕机器宕机,磁盘上的binlog也不会丢失

MySQL:binlog到底是个什么东西

基于binlog和redolog完成事务的提交

当我们把binlog写入磁盘文件之后,接着就会完成最终的事务提交,此时会把本次更新对应的binlog文件名称和这次更新的binlog日志在文件里的位置,都写入到redo log日志中,同时在redo log日志文件里写入一个commit标记。

在完成这个事情之后,才算最终完成了事务的提交、
MySQL:binlog到底是个什么东西

最后一步在redo日志中写入commit标记的意义是什么

意义: 用来保持redo log日志和binlog日志一致的。

我们来举个例子,假设我们在提交事务的时候,一共有上图中的5、6、7三个步骤,必须是三个步骤都执行完毕,才算是提交了事务。那么在我们刚完成步骤5的时候,也就是redo log刚刷入磁盘文件的时候,mysql宕机了,此时怎么办?

这个时候因为没有最终的事务commit标记在redo日志里,所以此次事务可以判定为不成功。不会说redo日志文件里有这次更新的日志,但是binlog日志文件里没有这次更新的日志,不会出现数据不一致的问题。

如果要是完成步骤6的时候,也就是binlog写入磁盘了,此时mysql宕机了,怎么办?

同理,因为没有redo log中的最终commit标记,因此此时事务提交也是失败的。

必须是在redo log中写入最终的事务commit标记了,然后此时事务提交成功,而且redo log里有本次更新对应的日志,binlog里也有本次更新对应的日志,redo log和bin log完全是一致的

后台IO线程随机将内存更新后的脏数据刷回磁盘

现在我们假设已经提交事务了,此时一次更新“update users set name=‘xxx’ where id=10”,执行器buffer pool中的缓存数据更新了,同时磁盘里有redo日志和binlog日志,都记录了把我们指定的“id=10”这行数据修改了“name=‘xxx’”。

但是这个时候磁盘上的数据文件里的“id=10”这行数据的name字段还是等于zhangsan这个旧值!

所以MySQL有一条后台的IO线程,会在之后某个时间里,随机的把内存buffer pool中修改后的脏数据刷回到磁盘上的数据文件里去。

MySQL:binlog到底是个什么东西
当上图中的IO线程把buffer pool里的修改后的脏数据刷回磁盘之后,磁盘上的数据才会跟内存里一样,都是name=xxx这个修改之后的值了。

在你IO线程把脏数据刷回磁盘之前,哪怕mysql宕机崩溃也没有关系,因为重启之后,会根据redo日志恢复之前提交事务做过的修改到内存里去,就是id=10的数据的name修改为了xxx,然后等待时机,IO线程自然还是会把这个修改后的数据刷到磁盘上的数据文件里去的

总结:InnoDB存储引擎的架构原理

从上面可以看出,InooDB存储引擎主要就是包含了一些buffer pool、redo log buffer等内存里的缓存数据,同时还包含了一些undo日志文件、redo位置文件等,同时mysql server自己还有binlog日志文件。

在你执行更新的时候,每条SQL语句,都会对应修改buffer pool里的缓存数据、写undo日志、写redo log buffer几个步骤。

当你提交事务的时候,一定会把redo log刷入磁盘,binlog刷入磁盘,完成redo log中的事务commit标记;最后后台的IO线程会随机把buffer pool里的脏数据刷入磁盘

上一篇:JVM内存模型


下一篇:SpringBoot高并发!mysql数据库字符集设置