当前位置: 代码迷 >> 综合 >> MYSQl 深入探索系列一 redo log
  详细解决方案

MYSQl 深入探索系列一 redo log

热度:60   发布时间:2023-12-24 23:24:09.0

目录

  1. 什么是redo log,记录了那些东西

  2. redo log 存储结构是怎样的

  3. redo log 作用是什么

  4. redo log 写入策略是怎样的

1 什么是redo log

简单的说 redo log 是mysql 底层存储引擎innodb的一种日志。最终是保存在磁盘的上的。

 

一条redo log中大致记录着有 日志类型,表空间id,数据页,数据页中的偏移量,具体修改的数据。也就是说记录了什么操作类型,操作了那个表空间的那个数据页,具体修改了那些值。

 

简单画个图

图片

2 redo log 存储结构是怎样的

redo log 在硬盘中真实以  表空间id+数据页id+数据页内偏移量+修改了几个字节的数据+实际修改数据 存储的么?肯定不是了。

 

redo log 真正的存储结构是mysql中的一个 block 块。这个block块分为 header body trailer 三部分,body中存放的是真正的数据,头部保存的是一些元数据(比如 body中存储了多少字节的数据,当前block的id多少,redo log的组,我们一个事务可能会有多个redo log,这些个redo log是同一个组里的)

 

3 redo log 作用是什么

根据上面我们提到的 redo log 存储的数据结构来看,大致可以猜应该是用来做数据恢复,备份啊之类的但是binlog中也有记录啊,怎么要多记录一份呢?里面存储的该行数据的最新信息,难道是容错用的?对的。redo log 是用来事务重做的。

 

怎么理解这个呢。其实很简单,mysql实际更新数据的时候先更新的内存,然后自何时的时候flush到磁盘上,这个时候如果down机了,此时数据还没来及flush到磁盘,内存中的数据会丢失的。

 

这个就涉及到mysql 执行一条sql语句时 整体流程了。我们后面再说,这里直接说redo log 了。mysql更新完内存中数据后会在binlog中记录当前事务 update xxxx 做归档。然后提交任务(其实就是写 redo log)。在redo log 中做个标记 当前事务执行到了那个binlog,偏移量是什么等等。

 

这样整个事务才算提交完毕。如果此时down 机 内存中的数据还么来及flush到磁盘上,mysql会扫描当前redo log 日志基于上面的记录找到对应的binlog 重新执行边流程。将数据重做到内存和磁盘上。

 

4 redo log 写入策略是怎样的

我们上面说到了redo log是写在一个个的 block中的,那是直接写硬盘么?肯定不是,会大大减低更新的性能。

 

mysql是先写吧redo log 写入到内存中,在何时的机会进行刷盘,但是redo log buffer 并不会向缓存页一样那么大默认16MB。毕竟一个block就512个字节 。

 

那什么时候才是flush redo log buffer 的时候呢?符合以下几点就会执行flush操作:

 

  1. 如果一个事务涉及到多个redo log 那肯定都要把这些同组的redo log都刷入磁盘,因为一个事务中要么都成功,要么都失败

  2. mysql 执行 shutdown的时候,会把所有的block flush到磁盘上。

  3. 异步线程每隔1秒就将buffer中的block flush到磁盘上。

  4. redo log buffer 容量占用一半的时候也会触发flush操作

 

疑问

细心的朋友发现redo log 只是用来事务重做,binlog 做归档,但是事务回滚在哪里做呢?大家想一想

 

我们下期再讲mysql是怎么做事务回滚的。

 

-------------------------------------------------------------------------------------------------------------

下面是个人公众号 < java架构的成长经历 >  欢迎关注

  相关解决方案