MySQL高级第十三篇:MySQL事物日志(redo日志-undo日志执行流程)

MySQL高级第十三篇:MySQL事物日志(redo日志-undo日志执行流程)

  • 一、概述
  • 二、redo 日志
    • 1. 为什么需要 redo日志?
    • 2. redo 日志的特点
    • 3. redo log 整体流程
    • 4. redo log 的刷盘策略?
  • 三、undo 日志
    • 1. 什么是 undo 日志,有什么作用?
    • 2. undo log与undo页
    • 3. 总流程

一、概述

  • 事务有4种特性:原子性、一致性、隔离性和持久性。

  • 事务的隔离性由锁机制实现,而事务的 原子性、一致性和持久性 由事务的 redo日志 和 undo日志 来保证。

  • REDO LOG : 重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。

  • UNDO LOG : 回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性、一致性。

  • REDO 和 UNDO 都可以视为是一种恢复操作,区别如下:

  • redo log:是存储引擎层(innodb)生成的日志,记录的是物理级别上的页修改操作,比如某页号、某偏移量写入了什么数据,主要为了保证数据的可靠性

  • undo log:也是存储引擎层(innodb)生成的日志,记录的是逻辑操作日志,比如对某一行数据进行了INSERT语句操作,那么 undo log 就记录一条与之相反的 DELETE 操作。主要用于事务的 回滚(undo log记录的是每个修改操作的逆操作)和 一致性非锁定读

二、redo 日志

1. 为什么需要 redo日志?

  • InnoDB存储引擎是以页为单位来管理存储空间的。在真正访问页面之前,需要把在磁盘上的页缓存到内存中的 Buffer Pool之后才可以访问。

  • 所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页会以一定的频率被刷入磁盘(checkPoint机制),通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就可以保证整体的性能不会下降太快。

  • 但是,因为checkPoint不是每次变更就触发,如果在commit之后刚写完缓冲池数据库宕机了,那么这部分数据就丢失了。

  • 这样就不能保证持久性,想要尽可能保证持久性,我们可以简单粗暴的,当内存中的数据修改了,我们就马上去更新磁盘,但是这样存在两个问题:

    • 1.InnoDB以页为单位进行磁盘IO,这就造成,当我们仅仅修改一个字节时,也不得不将一个完整的页刷新到磁盘。
    • 2.一条update语句可能修改很多页面,这些页面可能并不相邻,这时就需要进行很多的随机IO,随机IO刷新较慢
  • 怎样更好的解决上边的问题呢? 这时redo日志就来了。

  • 我们只是想要当事物提交之后,内存中的数据肯定改了,这时磁盘的数据也一定要能改。我们的思路就是不频繁刷盘,而是先将所做的修改保存到一个文件里边,这个文件起名叫做 redo日志,这样的话,就算修改内存还没来得及刷新磁盘宕机了,重启后也可以根据 redo日志 来恢复,以此来保证持久性。

  • InnoDB引擎的事务采用了WAL技术(Write-Ahead Logging),这种技术的思想就是先写日志,再写磁盘,只有日志写入成功,才算事务提交成功,这里的日志就是redo log,当发生宕机且数据未刷到磁盘的时候,可以通过redo log来恢复,以保证ACID中的D。
    MySQL高级第十三篇:MySQL事物日志(redo日志-undo日志执行流程)_第1张图片

2. redo 日志的特点

  • 降低的刷盘频率
  • 占用空间小,刷盘快
  • 顺序写入,顺序IO比随机IO快
  • 事物过程中,redo log不断记录

redo log跟bin log的区别:

redo log是存储引擎层产生的,而bin log是数据库层产生的。

一个事物过程中,会一直不断的往redo log顺序记录,而bin log不会记录,直到这个事务提交,才会一次写入到bin log文件中。

3. redo log 整体流程

redo log 整体流程大致分为四步:

  • 第1步:先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝;
  • 第2步:生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值;
  • 第3步:当事务commit时,将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写的方式
  • 第4步:定期将内存中修改的数据刷新到磁盘中
    MySQL高级第十三篇:MySQL事物日志(redo日志-undo日志执行流程)_第2张图片

4. redo log 的刷盘策略?

redo log 的刷盘策略,指的是将redo log buffer中的内容刷新到redo log file这一步,虽然它不是真正的将数据刷新到磁盘,但是,只要这一步不出现问题,就可以保证我们的持久化成功了

redo log 的刷盘策略由 innodb_flush_log_at_trx_commit 这个参数控制,值可以为 0,1,2,代表三种策略,默认为 1。

三种策略如下:

  • 值为0:表示每次事务提交时不进行刷盘操作。(系统默认master thread每隔1s进行一次重做日志的同步)
  • 值为1:表示每次事务提交时都将进行同步刷盘操作(默认)
  • 值为2:表示每次事务提交时都只把redo log buffer内容写入page cache,不进行同步。由OS自己决定什么时候同步到磁盘文件。

三、undo 日志

1. 什么是 undo 日志,有什么作用?

  • 其实,在事物更新数据之前,有一步写入 undo log 的操作,undo log 用来保证事物的原子性。

  • 当事物执行过程中出现各种错误时,这个事物需要回滚,把数据改回原先的样子,所以就需要 undo 日志 来记录旧值。

  • 此外,undo log 的产生会伴随着 redo log 的产生,因为 undo log 也需要持久性保护。

  • undo log 的作用:

    • 1.回滚数据
    • 2.MVCC(当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取。)

2. undo log与undo页

  • 写 undo log 时,会申请一个undo 页,在页中进行写入;
  • 但是为每一个事物分配一个页,是非常浪费内存的,所以undo页被设计为是可以重用的;
  • 当事务提交时,并不会立刻删除undo页,而是判断是否可以重用;
  • undo log 在 commit 后,会被放到一个链表中,然后判断undo页的使用空间是否小于3/4,如果小于3/4的话,则表示当前的 undo页 可以被重用,那么它就不会被回收,其他事务的 undo log 可以记录在当前undo页的后面。
  • 由于undo log是离散的,所以清理对应的磁盘空间时,效率不高。

3. 总流程

MySQL高级第十三篇:MySQL事物日志(redo日志-undo日志执行流程)_第3张图片

你可能感兴趣的:(MySQL高级,mysql,数据库,java,InnoDB)