扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

MySQL日志文件---Redo Log

2025/11/11
929
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

InnoDB使用Redo Log来保证数据的一致性和可持久化。因为Redo Log对MySQL具有非常重要的作用,所以本节主要介绍Redo Log。

Redo Log初探

MySQL采用的是WAL(Write-Ahead Logging)技术,也就是先写日志再写磁盘。如果有修改操作,则先将操作记录在Redo Log Buffer中,然后将Redo Log Buffer中的数据刷新到磁盘的日志文件中,最后写入数据文件中。Redo Log记录了这个页做了什么改动,对Redo Log进行落盘,不仅可以保证数据持久化,还可以提高写入效率。为什么说可以提高写入效率呢?这里介绍两点原因。

MySQL 如果每次都按页落盘,即使有少量数据的修改,每次落盘也是整个数据页,那么IO成本将会非常高。而Redo Log记录的是缓冲池中页的修改记录,因此每次只需要对Redo Log进行落盘,而不需要对整个页落盘。这大大降低了落盘的数据量,同时节约了IO成本,从而提高了写入效率。

如果每次都是将页落盘,那么页会在不同的位置,因此落盘时基本上就是随机IO;而有了Redo Log,只将Redo Log落盘,就可以将这些随机IO转换成顺序IO,这样也可以提高写入效率。

Redo Log另一个很重要的作用就是崩溃恢复能力。事务在提交时会把Redo Log刷新到磁盘中,如果此时系统宕机了,那么重启之后,只要根据Redo Log的记录把数据页未更新的部分更新一下,就可以恢复事务所做的数据变更。

Redo Log的落盘

Redo Log由两部分组成:Redo Log缓冲区和Redo Log文件。

Redo Log缓冲区的大小通过innodb_log_buffer_size参数来设置。当事务更新时,一半先写入 Redo Log 缓冲区,再写入 Redo Log 文件。而具体的写入频率由innodb_flush_log_at_trx_commit参数控制。innodb_flush_log_at_trx_commit参数有3个有效值,其对应的含义如下。

0,每秒将日志缓冲区写入日志文件一次,并在日志文件上执行磁盘刷新操作,未刷新日志的事务可能会在崩溃中丢失,此时InnoDB不再符合事务持久性的要求。

1,在每次提交事务时,日志缓冲区都会写入日志文件中,并在日志文件上执行磁盘刷新操作。

2,在每次提交事务后写入日志,并且日志每秒刷新一次到磁盘。未刷新日志的事务可能会在崩溃中丢失。当MySQL服务发生宕机,但操作系统没有发生宕机时,不会出现数据丢失。但是当操作系统宕机时,重启后可能会丢失 Redo Log缓冲中还没有刷新到Redo Log文件中的数据。

下面通过一个实验来对比innodb_flush_log_at_trx_commit参数的3个有效值的性能差异。

创建测试表和批量写入数据的存储过程如下:

设置innodb_flush_log_at_trx_commit参数取不同的值,并运行批量写入数据的存储过程:

innodb_flush_log_at_trx_commit参数的不同取值对数据写入的影响如表所示。

从上面的实验可以看出,innodb_flush_log_at_trx_commit参数设置为0或2的写入速度比设置为1的写入速度快很多。但是,如果某个MySQL实例将innodb_flush_log_at_trx_commit参数设置为0或2,那么它其实已经不具备ACID中的D(Durability,持久性)。在一般情况下,建议将innodb_flush_log_at_trx_commit参数设置为1,这样可以保证MySQL在崩溃恢复时数据不丢失。

Redo Log的数量及大小修改

MySQL启动后,Redo Log的大小和个数就是固定的,如可以配置3个大小为2GB的Redo Log,文件名类似于ib_logfile0。Redo Log是循环写的,如图所示。

从第一个文件ib_logfile0开始写,ib_logfile0写满了再写ib_logfile1,直到写到最后一个文件ib_logfile2,又继续从第一个文件ib_logfile0开始写。其中,write pos是当前记录的位置,一边写一边移动;CheckPoint是当前要擦除的位置,也是向后推移的。擦除记录前会确保记录已经更新到数据文件中。

Redo Log的几个重要参数如下。

innodb_log_group_home_dir:控制Redo Log的存放路径,如果没有配置该参数,那么Redo Log默认存放在数据目录下。

innodb_log_file_size:控制Redo Log的大小,默认值为48 MB,但不能超过512GB除以innodb_log_files_in_group参数配置的值,如果innodb_log_files_in_group参数的值为2,那么innodb_log_file_size参数的最大值为256 GB。

innodb_log_files_in_group:控制Redo Log的数量。

如果需要修改,则在配置文件的[mysqld]中补充类似于如下的配置:

这表示Redo Log有3个大小为2GB的文件,存放在目录“/data/mysql/data”下。

经验分享:

如果innodb_log_file_size参数设置得太小,则可能导致MySQL的Redo Log频繁切换,频繁地触发数据库的CheckPoint,刷新脏页的次数随之增加,从而影响IO性能。另外,如果有一个大的事务把所有的Redo Log写满了还没有写完,就会导致日志不能切换,MySQL可能就不能正常提供服务了。

innodb_log_file_size参数设置得太大,虽然可以提升IO性能,但是当MySQL宕机时,恢复的时间也会很长。

配置完成之后需要重启生效。对应的文件如下:

CheckPoint

CheckPoint是当前要擦除的位置,而Redo Log在擦除记录前会确保记录已经更新到数据文件中。因此,也可以认为CheckPoint就是控制数据页刷新到磁盘的操作。

CheckPoint的作用就是将缓冲池中的数据页刷新到磁盘。如果发生宕机重启,那么已经刷新的数据页不需要再进行恢复,只需要恢复CheckPoint之后的操作。

MySQL 8.0中的Redo Log归档

在数据备份过程中可能会复制Redo Log。如果MySQL频繁变更,那么复制Redo Log的速度就跟不上Redo Log的生成速度。因为Redo Log是以覆盖方式记录的,所以会丢失部分Redo Log。

MySQL 8.0.17引入了Redo Log归档(当然,这个功能在比较旧的版本中出现过,后面取消了),按照Redo Log记录顺序写入归档文件中,以解决备份时Redo Log丢失的情况。Redo Log的开启由innodb_redo_log_archive_dirs参数控制,具体的配置方法如下。

创建用于Redo Log归档的文件夹:

提醒: 归档目录必须满足以下条件。

目录必须存在,MySQL不会主动创建归档目录。

目录不能让系统中的其他用户访问。

不能与现有的一些目录重复,如datadir等。

启用Redo Log归档:

提醒:redolog-archiving 表示归档目录的标识符;“/data/mysql/redolog-archiving/”表示归档目录。

激活Redo Log归档:

提醒:redolog-archiving就是定义的归档目录的标识符,redo-20201222表示保存归档文件的目录的子目录。

判断归档和Redo Log是否存在:

MySQL 8.0中的Redo Log禁用

从MySQL 8.0.21开始可以禁用Redo Log。这一项功能可以应用在新实例的数据导入过程中,具体的实验过程如下。禁用Redo Log记录,直接执行下面的SQL语句:

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录