mysql面试关键知识点:redo log

redo log作用

重做日志redo log用来实现事务的原子性和持久性,即事务ACID中的A和D。本质上是一种恢复操作,恢复的是提交事务修改的页操作。

redo log组成

其由两部分组成:

一是内存中的重做日志缓冲(redo log buffer),其是易失的:

其大小也是由参数innodb_log_buffer_size标识,默认是16M,由log block 组成,每个log block 512字节。

二是重做日志文件(redo log file),其是持久的。

在默认情况下,在InnoDB 存储引擎的数据目录下会有两个名为ib_ logfile0 和ib_logfile1的文件。重做日志文件(redo log file)。它们记录了对于InnoDB 存储引擎的事务日志。ib_logfile0和ib_logfile1是循环覆盖的。

redo log buffer刷盘条件

什么时候redo log从内存buffer刷盘到redo log file磁盘文件中呢?触发这个操作的条件是什么呢?

  1. master thread每秒进行刷新

    innodb_flush_log_at_timeout参数,可以设置刷新间隔,默认为1

  2. redo log buffer使用大于1/2进行刷新

  3. 事务提交时进行刷新

参数innodb_flush_log_at_trx_commit={0|1|2} 对事务提交时进行刷新这个功能进行细粒度控制

  • 0 - 事务提交的时候并不把日志(redo log buffer)写入到磁盘(1s 或者redo log buffer使用大于1/2 时刷日志)
  • 1 - 事务每次提交的时候要确保日志(redo log buffer)写入磁盘,即使宕机,也可以通过redo恢复,达到持久性的要求(1为默认值)
  • 2 - 事务提交的时候,仅将日志(redo log buffer)写入到操作系统缓存

下面分析下这3种情况下,如遇问题,数据丢失的情况

  • 0 - 可能会有事务数据丢失。最坏的情况是丢失1秒的事务数据

  • 1 - 事务数据是不会丢失的

  • 2 - 如果是mysql实例挂了,那么在mysql重启后,由于数据仍在os缓存中,还是会继续写入redo日志的,不会丢失事务数据;但如果是服务器down了,那么这部分事务日志还是丢失了

redo log的记录结构

mysql日志的分类

  • 物理日志:记录整个页的变化(diff)

  • 逻辑日志:SQL语句

redo log可以看做是物理逻辑日志,其是根据页进行记录,记录的内容是like sql语句

其每条记录的结构
在这里插入图片描述

  • space + page_no 指定页
  • redo log body:记录逻辑日志,并不是记录sql语句,记录的是页的变化

格式如下面两个insert/delete格式
在这里插入图片描述

其物理结构是
在这里插入图片描述

redo log工作过程

redo log工作原理要与mysql事务提交过程一起分析,参考:mysql 事务提交底层处理过程(写操作)及redo log实现原子性及持久性分析

关于redo log的一些问题

问题1:redo log的写入是否需要double write?
redo log block的512个字节与磁盘扇区大小一样,所以重做日志的写入可以保证原子性,不需要double write。即redo log block的大小选择与磁盘扇区大小一样,是设计如此。

问题2:ib_logfile0和ib_logfile1是循环覆盖的,并不做归档。为什么不需要归档呢?
因为mysql有二进制日志来做归档。

问题3:重做日志缓冲一般不需要设置得很大,为什么呢?
因为一般情况下每一秒钟会将重做日志缓冲刷新到日志文件,因此用户只需要保证每秒产生的事务量在这个缓冲大小之内即可。

问题4:为什么要把重做日志文件设置得很大呢?

因为redo log是做覆盖的,一个一个512字节的block来写,可以被覆盖的部分是指这些redo log已经不再需要了,即当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分就可以被覆盖重用。

如果将要覆盖写一个block,但是这个block中对应的脏页还没有刷盘,要强制进行一次脏页的刷盘,产生checkpoint,将缓冲池中的页至少刷新到当前重做日志的LSN位置,那么写redo log就需要进行等待了,而导致mysql数据库性能有很大程度的下降。

问题5:为什么事务提交时进行刷新,即innodb_flush_log_at_trx_commit=1,不会丢失事务数据?

比如:在buffer pool中已经修改了,还没有刷到磁盘之前,数据库发生down机了,怎么办呢?

down机了,也没关系,因为每个页在修改的时候,都将日志写入了redo log。那么mysql重启了,通过回放redo log,还是可以实现磁盘数据更新了的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值