当前位置:   article > 正文

【MySQL】深入解析日志系统:undo log、redo log、bin log

undo log

前言

MySQL数据库提供了功能强大的日志系统,其中比较重要的是:undolog、redolog、binlog,今天来深入学习下这三个日志实现细节。

1、undo log

1.1、undo log 是什么

undolog一般叫回滚日志,事务回滚rollback功能就是通过undolog实现的,通过undolog保证了为事务原子性undolog主要功能如下:

  • 事务回滚
  • MVCC
1.2、事务回滚

当开启一段事务还未提交时,事务中的操作可能会出现错误异常,这时候就可以通过undo log将事务中的操作进行回滚(rollback),意思是回到事务开启前那个状态。例如:开启事务后我对表中某条记录进行修改(将该记录字段值由a ——> b ——> c),如果从整个修改过程中出现异常,事务就会回滚,字段的值就回到最初的起点(值为a)。

事务如何通过undo log进行回滚操作呢?这个很好理解,我们只需要在undo log日志中记录事务中的反向操作即可,发生回滚时直接通过undolog中记录的反向操作进行恢复,例如:

事务进行insert操作,undo log记录delete操作
事务进行delete操作,undo log记录insert操作
事务进行update操作(a改为b),undolog记录update操作(b改为a)

接下来了解一下事务是如何通过undo log完成回滚的(undo log版本链),对于InnoDB存储引擎而言,数据页中的每行数据都会分配两个字段:trx_idroll_pointer,在了解这个之后就通过一张图直观的表达undo log记录了:

在这里插入图片描述
上图中,trx_id代表事务id,记录了这一系列事务操作是基于哪个事务;roll_pointer代表回滚指针,就是当要发生rollback回滚操作时,就通过roll_pointer进行回滚,这个链表称为版本链

buffer pool 中有 undo 页,不仅对数据页修改操作会记录到redo log buffer,对 undo 页修改操作也会记录到 redo log buffer,这样就通过redo log保证了事务持久性

当事务Commit之后,undo 页本身就没有利用价值了,此时通过后台线程中的Master ThreadPurge Thread进行 undo 页 的回收工作。
在这里插入图片描述

2、redo log

2.1、redo log 是什么

redo log又称重做日志,保证了事务的持久性,当我们对缓冲池中的数据页进行了修改(修改后变成脏页),但是脏页数据是存在于Buffer Pool缓冲池,缓冲池占用的就是操作系统内存空间,所以数据页本质也是存在内存中的,内存有个特点就是断电即失

所以当脏页数据还没有刷入磁盘,此时数据库服务发生宕机,那么脏页数据就会因为宕机而丢失,如何恢复这些没刷盘得脏页数据呢?这时候redo log就派上了用场,具体流程可参考下图:
在这里插入图片描述

redo log通过WAL(Write-Ahead Logging)来进行故障恢复(crash-safe),所谓WAL大白话先写日志,后写磁盘。当我们对缓存页进行了修改后(变成脏页),我们就将本次操作写入到redo log buffer中,当事务Commit时就先将redo log buffer中记录通过后台线程刷到磁盘中(事务提交是redo log默认刷盘时机),此时脏页还没有刷入磁盘,但只要redo log成功刷盘就可以认为本次的修改操作完成了,因为就算发生了故障导致脏页数据丢失也可以通过磁盘redo log恢复,需要注意redo log记录的是物理操作,例如:对AAA数据页BBB偏移量位置做了CCC更新,这跟undo log区别还是挺大的:

事务提交崩溃,通过 undo log 回滚事务
事务提交崩溃,通过 redo log 恢复事务

2.2、redo log 刷盘

上面已经介绍过了,redo log记录先写入到redo log buffer中,然后通过后台线程进行刷盘,也就是说最后还是从 redo log buffer 同步到硬盘中,那么redo log buffer何时进行刷盘操作呢?主要是以下几种情况,默认情况下,redo log在事务提交时就会进行一次redo log刷盘:

  • Master Thread每秒刷盘一次
  • redo log buffer 剩余空间 < 1/2
  • 通过innodb_flush_log_at_trx_commit参数控制
    • 0:有事务提交的情况下,每秒刷盘一次
    • 1:每次提交事务,刷盘一次(默认,性能差)
    • 2:每次提交事务,把日志记录放到OS内核缓冲区,刷盘时机交给OS(性能好)

这有个疑问点,为啥事务提交时不直接将脏页刷盘呢,何苦还要将 redo log buffer 中记录进行刷盘,然后脏页再刷盘呢,这不多了一步流程吗?之所以多了 redo log 刷盘这步操作,主要原因:

redo log 刷盘操作采用磁盘顺序写方式进行的
缓存页刷盘操作采用随机写方式
顺序写随机写性能更优秀

2.3、redo log 硬盘文件

上面提到了redo log的刷盘操作采用顺序写方式进行,接下来咱们看下 redo log 文件在硬盘中是怎样的方式存在的。

redo log文件好像一个甜甜圈

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/970981
推荐阅读
相关标签