暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

细聊MySQL八股之redo log

34

写在文章开头

redo log
也就是所谓的重做日志,是innoDb
存储引擎独有的日志,它使得MySQL
在宕机情况下依旧可以redo log
完成数据具备恢复能力, 从而保证数据完整性,本文将针对该日志进行分析讲解,希望对你有帮助。

Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili

因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注  “加群”  即可和笔者和笔者的朋友们进行深入交流。

详解MySQL中的redo log

redo log的作用

redo log
InnoDB
存储引擎独有的日志,用于MySQL
工作过程中崩溃或者宕机时进行数据恢复的文件,从而保证数据的持久性以及完整性。

redo log是如何运行工作的

我们都知道数据库数据基本单位也是和操作系统一致的,都是以页为单位,我们以MySQL
数据查询为例,为了尽可能减少IO
次数,MySQL
在进行数据查询会优先将数据查询并存储到Buffer Pool
中。这样下次再有相同的查询就可以直接去Buffer Pool
中获取。 当我们需要对数据修改操作之后,这个修改操作就会优先被存放到redo log buffer
中,最终就会被刷盘并写入到redo log file
中。

redo log的刷盘时机

上文图解的第四步提到了redo log
刷盘的操作,当符合以下几种条件时,对应redo log buffer会被刷盘持久化到磁盘中:

  1. 事务提交:当事务提交时,log buffer
    redo log
    会按照innodb_flush_log_at_trx_commit
    的刷盘时机将数据持久化到磁盘中。
  2. log buffer
    空间不足:log buffer
    中的redo log
    已经占满该缓冲区一半时,缓冲区数据就会被刷到磁盘中。
  3. 事务日志缓冲区已满:InnoDB
    使用一个事务日志缓冲区(transaction log buffer)
    存储事务redo log
    的日志条目,当该缓存区已满时,就会触发日志刷新将日志写入磁盘中。
  4. checkpoint
    InnoDB
    会定时执行一个checkpoint
    ,将内存中那些已修改但还为持久化到磁盘的脏数据页写到磁盘中,在这期间也会将redo log
    一并持久化。
  5. 服务器优雅关闭:MySQL
    服务正常关闭时,这些缓冲区的数据就会写入到磁盘中。

redo log的刷盘策略

上文事务提交时提到一个刷盘策略的概念,实际上写入磁盘的时机是由MySQL
系统参数设置决定的,我们可以键入下面这条SQL
查看innodb_flush_log_at_trx_commit
这个参数的设定值:

SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';

以笔者的MySQL8
为例,默认情况下这个参数值为1:

当这个值为0时,每次进行修改写入到redo log buffer
,然后redo log buffer
会将数据写到page cache
中,由log thread
每个1s调用操作系统函数fsync
将数据写入到redo.file
中。很可能因为服务器崩溃或者宕机导致丢失1s的数据。

1为默认值,当参数值设置为1时, 每次进行修改操作后将数据写入到redo log buffe
r中,一旦事务被提交,就会自动调用操作系统函数fsync
将数据写入的磁盘中的redo.file
文件中。若设置为这个级别,当服务器宕机,若当前事务没有提交,这部分数据丢失也无妨,事务提交的话,那么这个操作就会被写到磁盘中,照样可以恢复。

配置为3时整体是和1差不多的,区别是写入page cache
之后并不是每隔1s将数据写入到磁盘中,而是当page cache
满了之后才会将数据写入到redo.file
中。注意,设置为3出现宕机或者服务器挂了的情况,这种策略性能表现最出色,但有可能会损失1s的数据。

redo log的日志文件组

redo log
并不是单指一个文件,它是由一组日志文件构成的,如下图所示,这些文件大小都是一样的,写入操作时依次从从1开始写,文件1写满了,就将数据写到文件2,最后写到文件4。

redolog通过write pos
标记当前写入的位置,每次完成写入write pos
标志位后移,一旦write pos
checkpoint
相遇时就说明文件满了,此时innodb
就会通过让checkpoint
往后移进行一些空间数据擦除,以此来保证一个足够空间容纳新数据。

为什么InnoDB不索引直接将数据写入磁盘呢?

页是操作系统的基本单位,一页差不多16kb
,而我们每次操作的数据可能也就x byte
,为了x byte
的数据操作将一页的数据进行同步持久化实在有些大材小用了,所以通过redo log buffer记录修改内容,通过刷盘策略进行数据输盘更新,由此提升数据库的并发能力,

小结

自此我们将redo log作用、工作机制、设计思想说分析完成,希望对你有帮助。

我是 sharkchiliCSDN Java 领域博客专家开源项目—JavaGuide contributor,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili 。 因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注  “加群”  即可和笔者和笔者的朋友们进行深入交流。

参考

MySQL三大日志(binlog、redo log和undo log)详解:https://javaguide.cn/database/mysql/mysql-logs.html


文章转载自写代码的SharkChili,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论