Mysql系列-Redo log日志

本文深入探讨Mysql的Redolog机制,包括其作用、结构、持久化方式及组提交优化,解析Redolog在事务持久化和数据库恢复中的关键角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mysql系列–事务日志中,我们介绍了Mysql中的事务日志,这里主要介绍Mysql事务日志中的Redo log日志。

Redo log是什么?

Redo log是重做日志,提供前滚操作。Redo log是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成什么样的。Redo log用来恢复提交后的物理数据页,但只能恢复到最近一次提交的内容。

Redo log包括两部分:内存中的日志缓存(log buffer)和磁盘上的日志文件(log file),其中日志缓存是易失的,日志文件是持久化的。

在Innodb存储引擎中,Redo log是以块为单位进行存储的,称为Redo log block,每个块占512字节,因此log buffer(内存日志)、os buffer(文件系统缓存)以及redo log file on disk(日志文件)都是以512字节的块存储的。

Redo log block由三部分组成:日志块头(12)+日志数据(492)+日志块尾(8),当数据页的修改较多需要超过492字节的日志记录时,就会使用多个Redo log block来记录数据页的修改。

Redo log是以顺序的方式追加到文件尾,并且Redo log的文件大小(由innodb_log_file_size指定)是固定的,当文件满时必须要先刷盘才能继续写,这会影响Mysql的性能。为了解决这个问题,引入了Redo log group的概念,即group中存在多个Redo log文件,每次只使用其中一个Redo log文件,当写满了就切到另一个Redo log文件,并触发Redo log的刷盘。group中Redo log文件的个数由参数innodb_log_files_group控制,默认为2。

需要注意,group只是一个逻辑概念,并没有真实文件目录来表示该group,Redo log的存储位置是由参数innodb_log_group_home_dir指定的,默认在datadir下。
Redo log文件大小对性能影响较大,当文件大小较大时,通过Redo log恢复时间就较长,当文件大小较小时,会导致频繁切换Redo log。

Redo log持久化

在概念上,Innodb通过force log at commit机制实现事务的持久化,即在事务提交的时候,必须先将该事务的所有事务日志写入到redo log file和undo log file中进行持久化。在事务持久化的过程中,通过DoubleWrite技术来保证Redo log正确的持久化。

为了提升事务提交性能,Redo log一般都是先写入log buffer中,在后续合适时机将log buffer写入到log file中进行持久化,即刷盘。由于log buffer中的数据是存在内存中,是易失的,为了尽可能减少事务提交后数据丢失的影响,可以通过innodb_flush_log_at_trx_commit 控制redo log的刷盘,取值0、1、2:

  • 0 : 提交事务的时候,不立即把 redo log buffer 里的数据刷入磁盘文件的,而是依靠 InnoDB 的主线程每秒执行一次刷新到磁盘。此时可能你提交事务了,结果 mysql 宕机了,然后此时内存里的数据全部丢失。
  • 1 : 提交事务的时候,就必须把 redo log 从内存刷入到磁盘文件里去,只要事务提交成功,那么 redo log 就必然在磁盘里了。注意,因为操作系统的“延迟写”特性,此时的刷入只是写到了操作系统的缓冲区中,因此执行同步操作才能保证一定持久化到了硬盘中。
  • 2 : 提交事务的时候,把 redo 日志写入磁盘文件对应的 os cache 缓存里去,而不是直接进入磁盘文件,可能 1 秒后才会把 os cache 里的数据写入到磁盘文件里去。

除此之外,还存在以下场景触发日志刷盘动作:

  • 定时刷盘(默认1s一次),这个刷日志频率由innodb_flush_log_at_timeout控制。
  • Log buffer中已使用内存超过一半
  • 当有checkpoint时,checkpoint是指检查点,可以加快Mysql的重启恢复过程,在重启恢复过程中,只需要恢复checkpoint之后的日志。c heckpoint在一定程度上可以代表已刷盘的日志位置。

Redo log组提交

当innodb_flush_log_at_trx_commit=1时,在事务每次commit时,仍然需要有一次日志刷盘操作,这个操作将会成为事务并发的瓶颈。为了解决这个问题,Mysql提出了Redo log组提交,即将同时提交的事务一次刷盘,注意这里不是等待一段时间后批量刷盘,而是将同时提交的事务一次性刷盘。

实现Redo log组提交需要依赖LSN(Log Sequence Number),LSN是单调递增的,当多个事务同时提交时,按照以下流程执行:

  1. 获取log_mutex
  2. 若flushed_to_disk_lsn >= lsn,表示日志已经被刷盘,跳转5
  3. 若current_flush_lsn >= lsn,表示日志正在被刷盘,跳转5后进入等待状态
  4. 将小于lsn的日志刷盘(组提交)
  5. 释放log_mutex

在第4步中,在刷盘的过程中,顺便把较小的lsn对应的事务一起刷盘。

LSN不仅可用于Redo log组提交,还可以用于checkpoint。LSN占用8字节,包含以下信息:数据页的版本信息、写入的日志总量,通过LSN开始号码和结束号码计算和检查点的位置

LSN不仅存在于redo log中,还存在于数据页中,在每个数据页的头部,有一个fil_page_lsn记录了当前页最终的LSN值是多少。由于redo log和数据同时存在于内存和磁盘中,内存和磁盘间的数据存在一定的延迟,因此会有4个LSN。

可以通过show engine innodb status查看当前lsn相关信息。
在这里插入图片描述

在进行数据恢复过程中,通过数据页中的LSN值和redo log中的LSN值比较,如果数据页中的LSN值小于redo log中LSN值,则表示数据丢失了一部分,这时候可以通过redo log的记录来恢复到redo log中记录的LSN值时的状态。

数据刷盘时机-checkpoint

上文介绍了Redo log的刷盘,而数据也是以数据页的形式存在内存中,也是需要将其刷盘的。触发数据刷盘的规则只有一个:checkpoint,但触发checkpoint的场景有多个。当checkpoing触发后,将会把脏数据页和脏日志页都刷到磁盘中。
checkpoint目的有:

  • 缩短数据库的恢复时间
  • 数据页(buffer pool)不够用时,将数据脏页刷到磁盘
  • redo log不可用时,将日志脏页刷到磁盘

checkpoint分为两类:

  • sharp checkpoint:完全检查点,数据库正常关闭时,会触发将所有脏页(日志和数据)写回磁盘。在数据库正常运行过程中,不会触发sharp checkpoint。
  • fuzzy checkpoint:模糊检查点,当满足一定的条件部分刷盘,一次只刷一部分,避免全局刷盘造成Mysql系统的卡顿。在数据库正常运行期间发生,存在4种情况触发该检查点。

触发fuzzy checkpoint的场景:

  • master thread checkpoint:异步以每秒或10秒从缓冲池的脏页列表中刷一定比例页到磁盘中。可以通过innodb_io_capacity控制刷脏页数。
  • flush_lru_list checkpoint: Mysql需要保证有足够可用的空闲页,当不足时从lru列表中移除足够的页,当这些页有脏页时,就会触发checkpoint。在5.6以后的版本,由page cleaner线程负责保证有足够的可用空闲页。通过innodb_lru_scan_depth可以控制可用页的数量。
  • async/sync flush checkpoint:log file快满时,会批量触发数据页的回写,根据log file不可被覆盖的比例可分为同步刷盘和异步刷盘,当达到75%,则触发异步刷盘,当达到90%,则触发同步刷盘。在5.6以后的版本,由page cleaner线程负责保证有足够可用的log file。
  • dirty page too much checkpoint:脏页太多检查点,为了保证buffer pool的空间可用性。脏页的比例由参数innodb_max_dirty_pages_pct控制。

更多精彩,请关注
在这里插入图片描述

<think>嗯,用户想了解如何在MySQL中查看redo log日志。首先,我得回忆一下MySQLredo log的结构和存储方式。根据之前的引用资料,redo log包括内存中的缓冲区和磁盘上的文件,比如引用[4]提到redo log分为内存redo log buffer和磁盘redo log file。所以用户可能想查看这两个部分的信息,但需要知道MySQL通常不直接让用户查看redo log文件的内容,因为这些是内部的、二进制的日志,用于崩溃恢复和事务的持久性。 接下来,我需要考虑用户的实际需求。用户可能是想监控redo log的状态,比如当前的使用情况、文件大小、写入情况等,或者是想查看具体的日志内容。但直接查看文件内容可能不可行,因为redo log是二进制格式,MySQL没有提供直接的工具来解析。不过,可以通过一些系统变量或命令来获取相关信息。 根据引用[1],提到了innodb_redo_log_capacity变量,这可能是一个新的配置参数,用于设置redo log的容量。在较新的MySQL版本中,用户可能需要查看这些参数来了解redo log的配置。此外,还有像innodb_log_files_in_group和innodb_log_file_size这样的变量,但可能在8.0之后被替换了。 另外,引用[3]和[5]提到redo log的状态,比如prepare和commit阶段,这涉及到事务的恢复过程。用户可能想通过某些命令查看当前redo log的状态,或者事务的状态。 可能的步骤包括: 1. 使用SHOW ENGINE INNODB STATUS命令,查看InnoDB的状态信息,其中包含了redo log的相关信息,比如日志序列号、写入位置等。 2. 查看系统变量,如innodb_redo_log_capacity、innodb_log_files_in_group等,来了解redo log的配置。 3. 使用性能模式(performance_schema)中的表来监控redo log的活动,比如events_waits_current表。 4. 对于实际文件,虽然不能直接查看内容,但可以查看文件的位置和大小。MySQL 8.0之后,redo log文件默认在数据目录下的#innodb_redo目录中,文件名类似redo_log_fileN。 需要注意的是,直接解析redo log文件内容需要专门的工具,这可能比较复杂,且官方不推荐。因此,用户可能需要使用间接的方法来监控和查看redo log的状态,而不是具体的内容。 另外,用户可能需要了解如何调整redo log的大小或配置,这可能涉及到修改系统变量,如引用[1]提到的innodb_redo_log_capacity。在回答时,需要区分不同MySQL版本的方法,因为8.0.30前后可能有变化。 总结下来,查看redo log的方法包括检查系统变量、InnoDB状态、文件位置以及性能模式中的监控数据。对于具体内容,可能需要使用第三方工具或MySQL的调试功能,但通常不建议这样做。</think>### 如何在MySQL中查看redo log日志? #### 1. **查看redo log配置参数** MySQL通过系统变量控制redo log的容量和文件数量。对于MySQL 8.0.30及之后的版本,使用以下命令: ```sql SHOW VARIABLES LIKE 'innodb_redo_log_capacity'; ``` 这会显示当前分配的redo log总容量(默认约104857600字节,即100MB)[^1]。早期版本可使用`innodb_log_files_in_group`和`innodb_log_file_size`查看文件数量和单个文件大小。 #### 2. **查看redo log文件物理位置** 默认情况下,redo log文件存储在MySQL数据目录的`#innodb_redo`子目录中,文件名格式为`redo_log_fileN`(例如`redo_log_file0`)。通过以下命令定位文件路径: ```sql SHOW VARIABLES LIKE 'datadir'; ``` #### 3. **监控redo log状态** 通过`SHOW ENGINE INNODB STATUS`查看InnoDB引擎状态,重点关注`LOG`部分: ``` LOG Log sequence number 1234567890 # 当前LSN(日志序列号) Log buffer assigned up to 1234567890 # 缓冲区已分配量 Log buffer completed up to 1234567890 # 缓冲区已写入量 Log flushed up to 1234567890 # 已刷盘LSN Pages flushed up to 1234567890 # 数据页刷盘LSN ``` `Log sequence number`表示最新的日志位置,`Log flushed up to`表示已持久化的日志位置,两者的差异反映未刷盘的日志量。 #### 4. **通过性能模式监控** 启用Performance Schema后,可查询redo log相关事件: ```sql SELECT * FROM performance_schema.events_waits_current WHERE EVENT_NAME LIKE '%innodb%log%'; ``` 此方法用于分析redo log的写入等待事件,帮助诊断性能问题。 #### 5. **解析redo log内容(高级)** MySQL未提供直接解析redo log的工具,但可通过以下方法间接分析: - **启用调试模式**:编译时开启`WITH_DEBUG`选项,使用`innodb_redo_log_reader`工具(仅限开发环境)。 - **第三方工具**:如Percona的`redo_log_parser`,需谨慎使用。 #### § 注意事项 - redo log是二进制文件,直接查看需特殊工具。 - 生产环境不建议修改redo log文件,可能破坏事务一致性。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yuzhiyuxia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值