重做日志-redo log

1、设计思路

  可以先说:为什么要引入内存(buffer pool)?

  mysql中的数据是存储在硬盘中的,读、写数据都需与磁盘进行交互。如读取数据,首先从磁盘中获取到数据,然后放到内存中,待到下次同样的查询直接从内存中获取;再如,更新数据依然是先从磁盘获取数据存放到内存,然后对内存中的数据更改完毕后,再进行刷盘的操作,以此完成写操作。

  对于少量数据,数据库可以接受,但是对于大量数据以及访问量,数据库一时的磁盘IO次数将会大大增加,势必给其带来不少的压力,以至于数据库会崩溃。

  为了解决这一问题,我们可以从刷盘处入手,当数据需要更新时,先使用一个文件对更新操作进行记录,然后再更新内存,在适当的时候对数据进行统一的刷盘操作,而这个文件就是redo log,该技术也被称为WAL技术,WAL的全称是Write-Ahead Logging,即先写日志,再写磁盘。该技术主要就是为了减少sql执行期间的数据库io操作次数,并且更新磁盘往往是在Mysql比较闲的时候,这样就大大减轻了Mysql的压力。

  此外,当内存中的脏页进行刷盘,而MySQL宕机时,如果没有redo log的话,修改后的数据就会丢失。

2、redo log介绍

  首先,提出一个问题:redo log是否对其文件大小有限制?若有限制,当超过其限制时,数据库会做出怎样对应的操作?

  解一:redo log文件的大小

InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是 1GB,那么这个日志总共就可以记录4GB的操作。并且写redo log是环状写日志的形式,如下图。

  • write pos是当前记录的位置,一边写一边后移。
  • check point是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

规定:write pos和checkpoint之间的是日志上还空着的部分,可以用来记录新的操作。如果write pos 追上checkpoint,表示日志满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint推进一下。

总结:有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe。

3、产生的 redo log 是直接写入磁盘的吗?

  实际上,执行一个事务的过程中,产生的 redo log 也不是直接写入磁盘的,因为这样会产生大量的 I/O 操作,而且磁盘的运行速度远慢于内存。

  所以,redo log 也有自己的缓存—— redo log buffer,每当产生一条 redo log 时,会先写入到 redo log buffer,后续在持久化到磁盘如下图:

  redo log buffer 默认大小 16 MB,可以通过 innodb_log_Buffer_size 参数动态的调整大小,增大它的大小可以让 MySQL 处理「大事务」是不必写入磁盘,进而提升写 IO 性能。

4、redo log 的刷盘时机?

  缓存在 redo log buffer 里的 redo log 还是在内存中,它主要有下面几个刷盘时机:

  • MySQL 正常关闭时;
  • 当 redo log buffer 中记录的写入量大于 redo log buffer 内存空间的一半时,会触发落盘;
  • InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘。
  • 每次事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值