MySQL数据库日志之为什么需要redo log?

为什么需要 redo Log?

redo Log(重做日志)是 InnoDB 引擎独有的,他让 MySQL 拥有了崩溃恢复的能力。

  • 比如 MySQL 实例挂了或者宕机了,重启时,InnoDB 存储引擎使用 redo log 恢复数据,保证数据的持久性和完整性。

redo log 运行的流程

流程:查询和更新

  1. MySQL 中数据是以页为单位,你查询一条数据,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放到 Buffer Pool 中。
  2. 后续的查询都是先从 Buffer Pool 中找,没有命中再去硬盘中找,减少硬盘 IO 开销,提升性能。
  3. 更新数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。
  4. 然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log Buffer)里,接着刷盘 到 redo log 文件中。

每条 redo 记录包含:表空间号+数据页号+偏移量+数据修改长度+具体修改数据

redo log 刷盘到磁盘,所以也叫物理日志

刷盘的时机

理想的情况,事务一提交就会进行刷盘操作,但实际上刷盘的时机是根据策略来进行的。

InnoDB 存储引擎为 redo log 的刷盘策略提供了【innodb_flush_log_at_trx_commit】参数,支持三种策略:

  • 0:设置为 0,表示每次事务提交时不进行刷盘操作(系统会自动刷盘)。
  • 1:(默认值)设置为 1,每次事务提交时都将进行刷盘操作。
  • 2:设置为 2,每次事务提交时都只把 redo log Buffer 写入 page cache(文件系统缓存)。

参数为 1 时,当事务提交时会调用 fsync 对 redo log 进行刷盘,不会有损失。

另外,InnoDB 引擎有一个后台线程,每隔一秒,就会把 redo log Buffer 中的内容写到文件缓存系统,然后调用 fsync 刷盘。

所以,0 和 2,都是后台线程刷盘,那么一旦异常,可能都会损失 1 秒的数据

2,宕机才会损失,MySQL 挂了,1 会损失 2 不会损失。

  • 因为 MySQL 挂了,buffer Pool 缓存中的数据会没,但是磁盘缓存不会 page cache

三种策略的流程图

innodb_flush_log_at_trx_commit=0

为 0 时,如果 MySQL 挂了,或者宕机了,可能会丢失 1 秒数据,因为不主动刷盘,靠后台系统线程 1 秒轮询刷盘,或者 redo log buffer size 容量到一半,线程刷盘。

innodb_flush_log_at_trx_commit=1

为 1 时,只要事务提交成功,redo log 记录就一定在硬盘中,不会丢失数据。

事务提交就会主动刷盘,如果事务执行期间 MySQL 挂了或者宕机了,日志丢了,但是事务没有提交,所以日志丢了没损失。

innodb_flush_log_at_trx_commit=2

为 2 时,事务提交,redo log buffer 中的内容只写入文件系统缓存(page cache)。

如果 MySQL 挂了不会有任何影响,但是宕机了可能会损失 1 秒数据。

redo log 在硬盘的存储形式--日志文件组

硬盘上存储的 redo log 日志文件不止一个,而是以一个日志文件组的形式出现的,每个 redo 日志文件大小都是一样的。

比如可以配置为一组 4 个文件,每个文件的大小是 1GB,整个 redo log 日志文件组可以记录 4G 的内容

他采用的是环形数组形式,从头开始写,写到末尾又回到头循环写。

在整个日志文件组中还有两个重要的属性,分别是 write pos,checkpoint

  • write pos :是当前记录的位置,一边写一边后移。
  • checkpoint:是当前要擦除的位置,也是往后移。

每次刷盘 redo log 记录到日志文件组中,write 位置就会后移更新。

每次 MySQL 加载日志文件组恢复数据时,会清空加载过的 redo log 记录,并把 checkpoint 后移更新。

  • write pos 和 checkpoint 之间还空的部分可以用来写入新的 redo log 记录。
  • 如果 write pos 追上 checkpoint,表示日志文件组满了,这个时候就不能写入新的 redo log 记录,MySQL 得停下来,清空一些记录,把 checkpoint 推进一下。

redo log 小结

我们知道到了 redo log 的作用,运行流程、刷盘时机、存储形式。

问题:为什么需要 redo log 来刷盘?而不是把修改后的数据页直接刷盘,有什么区别?

1Byte = 8bit

1KB = 1024 Byte

首先,数据页的大小是 16KB,刷盘比较耗时,可能就修改数据页里的几 Byte,那就没有必要把完整的的数据页刷盘。

而且,数据页刷盘是随机写,因为一个数据页对应的位置可能在硬盘文件的随机位置,性能很差。

但是,写 redo log,一行记录可能就占几十 Byte,再加上是顺序写,所以刷盘数据很快。

所以,redo log 形式记录修改内容,性能会远远超过刷数据页的方式,这也能提升数据库的并发能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值