服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - MySQL事务未提交Redolog能持久化到磁盘吗?

MySQL事务未提交Redolog能持久化到磁盘吗?

2024-01-02 14:16小许code Mysql

我们知道持久化的目的是可以在数据丢失后进行恢复,保证数据不丢失,对于MySQL来说只要 binlog 和 redolog 都能正确持久化到磁盘上,就可以保证数据不丢失了。

今天的文章内容围绕一位网友的评论去展开,在看完小许文章【结合MySQL更新流程看 undolog、redolog、binlog】,他提出了这么一个问题,如下:

MySQL事务未提交Redolog能持久化到磁盘吗?图片

换个方式提取出他想问的:可以理解为如果在redolog持久化过程中,意外情况导致事务未提交,那是不是redolog就写入不了磁盘了?

本期内容就从这个问题进行展开要讲的内容!

我们知道持久化的目的是可以在数据丢失后进行恢复,保证数据不丢失,对于MySQL来说只要 binlog 和 redolog 都能正确持久化到磁盘上,就可以保证数据不丢失了。

那意外情况导致事务还没提交的时候,redolog 能不能被持久化到磁盘呢?

先公布答案,确实有可能会!

为什么会有这种可能呢,难道是被动刷盘了?先不着急想象,我们接着往下看,这个问题今天必须拿下!

MySQL事务未提交Redolog能持久化到磁盘吗?图片

redo log可能存在的位置

没看过开头提到的文章建议返回去看下,这里再进行下核心知识点的回忆。

redo log 其实记录的是此次事务「完成后」的数据状态,记录的是更新之后的值。

我们来回顾看下redolog的写入流程:

MySQL事务未提交Redolog能持久化到磁盘吗?图片

1. 修改操作时先将原始数据从磁盘中读入内存中来,修改数据,如图中的脏页

2. 此时产生日志写入redo logbuffer,记录的是数据被修改后的值

3. 当事务commit时,将redo logbuffer中的内容采用追加方式刷新到redo logfile

4. 调用fsync将修改的数据刷新到磁盘中

也就是说redolog可能存在于三种位置状态:

MySQL事务未提交Redolog能持久化到磁盘吗?图片

redolog buffer:

写入redo log buffer就用到了的WAL(Write-Ahead Logging)技术,日志先写入redo log buffer缓冲区

page cache:

page cache是文件系统缓冲,如果是写到磁盘,但是没有持久化(fsync),物理上是在文件系统的page cache里面

硬盘disk:

从page cache 持久化到磁盘,也就是磁盘中的redo log file中,你在data目录中看到的ib_logfile文件就是实际的redo log日志文件,它以文件组的形式出现的。这些文件以ib_logfile[数字](数字可以是0、1、2..)的形式进行命名。

事务提交的过程

一般来说事务的提交也应该有以下三个过程:

MySQL事务未提交Redolog能持久化到磁盘吗?图片

写磁盘策略

缓存在 redo log buffer 里的 redo log 是在内存中的,最终是要刷到磁盘中。

那么redo log是如何被控制写入刷入磁盘的呢?

这就涉及到redo log的刷盘策略了

InnoDB通过innodb_flush_log_at_trx_commit 参数可以控制策略,该参数控制 commit 提交事务时,如何将 redo log buffer中的日志刷新到 redo log file 中,它支持设定0,1, 2也就是说支持三种策略设置。

这个策略我们可以用参数设置:

show variables like 'innodb_flush_log_at_trx_commit'
//默认情况下 innodb_flush_log_at_trx_commit值是1

Innodb存储引擎有一个后台线程,每隔1秒,就会把 redo log buffer 中的内容写到文件系统缓存(Page Cache),然后调用fsync进行刷入到磁盘的操作。

延迟写

设置为0(延迟写) :每次事务提交时不主动进行刷盘操作,redo log依然留在redo log buffer中,然后后台进程每秒写入page cache中,然后持久化到磁盘中。

MySQL事务未提交Redolog能持久化到磁盘吗?图片

实时写,实时刷

设置为1 (实时写,实时刷):每次事务提交时都会直接将缓存在redo log buffer中的redo log直接持久化到磁盘中( 默认值 )。

MySQL事务未提交Redolog能持久化到磁盘吗?图片

实时写,延时刷

设置为2(实时写,延时刷) :表示每次事务提交时都只把 redo log buffer 内容写入 page cache,不进行同步,由os自己决定什么时候同步到磁盘文件。

MySQL事务未提交Redolog能持久化到磁盘吗?图片

事务未提交写磁盘的情况

看了redo log可能存在的状态和位置,以及写盘策略,那跟事务是否提交redo log能否写入磁盘有啥关系呢。

那我们看下面几种情况是不是在事务没提交的时候也可能会写入到磁盘呢!

后台线程每隔1s刷新

上面我们说到InnoDB 有一个后台线程,每隔 1 秒轮询一次,具体的操作是这样的:调用 write 将 redolog buffer 中的日志写到文件系统的 page cache,然后调用 fsync 持久化到磁盘。

那么写入到redolog buffer中的redo log在事务没提交的时候,可能就会后台线程在持久化的时候被一起持久化到磁盘中。

其他事务提交成功

我们在设置写盘策略的时候 innodb_flush_log_at_trx_commit 设置为1,在每次事务提交的时候都会直接将缓存在redo log buffer中的redo log直接持久化到磁盘中。

举个栗子,事务 A 执行到一半,此时 redolog 到 redolog buffer 中,这时候有另外一个事务 B 提交,事务 B 要把 redolog buffer 里的日志全部持久化到磁盘,这时候就会带上是不是事务 A 在 redolog buffer 里的日志一起持久化到磁盘。

(⊙o⊙)…

redo log buffer 空间快满了

另一种说法是当redo log buffer 占用的空间达到 redolog buffer 大小一半的时候,后台线程会主动写盘。

redo log buffer 占用空间由参数 innodb_log_buffer_size 控制,默认是 8MB

但是这个写盘动作只是 write 到了文件系统的 page cache,仍然是在内存中,并没有调用 fsync 真正落盘。

朋友们下次当面试官问你:事务还没提交的时候,redo log 能不能被持久化到磁盘呢?

你应该知道如何回答了吧,哈哈,拿下!

原文地址:https://mp.weixin.qq.com/s/Bmy7eofHKepcdo0d6rILMQ

延伸 · 阅读

精彩推荐
  • Mysql浅谈mysql的中文乱码问题

    浅谈mysql的中文乱码问题

    本文主要给大家分享了本人在项目中遇到的一些mysql中文乱码的问题的解决方法,非常简单实用,这里推荐给大家,有需要的小伙伴可以参考下。 ...

    MYSQL之家2262020-04-30
  • MysqlMySQL多线程复制遇到Error_code: 1872的解决方案

    MySQL多线程复制遇到Error_code: 1872的解决方案

    本文给大家分享的是在使用mysql主从复制的时候遇到Error_code: 1872错误的解决方法,非常的简单,有需要的小伙伴可以参考下...

    InsideMySQL3122020-06-23
  • Mysqlmysql 8.0.20 安装配置方法图文教程

    mysql 8.0.20 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.20 安装配置方法图文教程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    mr_five558562021-01-16
  • Mysqlmysql间隙锁加锁11个规则(案例分析)

    mysql间隙锁加锁11个规则(案例分析)

    这篇文章主要介绍了mysql间隙锁加锁11个规则 ,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    Mr.LUCKY8752023-03-30
  • MysqlmacOS下mysql 8.0.16 安装配置图文教程

    macOS下mysql 8.0.16 安装配置图文教程

    这篇文章主要为大家详细介绍了macOS下mysql 8.0.16 安装配置图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    weixin_422445515002020-12-01
  • Mysql深入理解MySQL主从复制线程状态转变

    深入理解MySQL主从复制线程状态转变

    这篇文章主要给大家介绍了关于MySQL主从复制线程状态转变的相关资料,文中介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    彭东稳7752019-06-06
  • Mysql一文弄懂MySQL索引创建原则

    一文弄懂MySQL索引创建原则

    在关键字段的索引上建与不建索引,查询速度相差近100倍,但差的索引和没有索引效果一样,索引并非越多越好,因为维护索引需要成本,下面这篇文章主要给大...

    Zerooooooooooooooooo6702022-02-25
  • MysqlMySQL对JSON类型字段数据进行提取和查询的实现

    MySQL对JSON类型字段数据进行提取和查询的实现

    本文主要介绍了MySQL对JSON类型字段数据进行提取和查询的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    慕城南风6002022-10-24