千家信息网

InnoDB Redo Flush及脏页刷新机制深入分析

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,概要:我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页。既然有重做日志保证数据持久性,查询时也可以直接从缓冲
千家信息网最后更新 2026年11月01日InnoDB Redo Flush及脏页刷新机制深入分析

概要:


我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页。既然有重做日志保证数据持久性,查询时也可以直接从缓冲池页中取数据,那为什么还要刷新脏页到磁盘呢?如果重做日志可以无限增大,同时缓冲池足够大,能够缓存所有数据,那么是不需要将缓冲池中的脏页刷新到磁盘。但是,通常会有以下几个问题:

  • 服务器内存有限,缓冲池不够用,无法缓存全部数据
  • 重做日志无限增大成本要求太高
  • 宕机时如果重做全部日志恢复时间过长
事实上,当数据库宕机时,数据库不需要重做所有的日志,只需要执行上次刷入点之后的日志。这个点就叫做Checkpoint,它解决了以上的问题:
  • 缩短数据库恢复时间
  • 缓冲池不够用时,将脏页刷新到磁盘
  • 重做日志不可用时,刷新脏页

重做日志被设计成可循环使用,当日志文件写满时,重做日志中对应数据已经被刷新到磁盘的那部分不再需要的日志可以被覆盖重用。

InnoDB引擎通过LSN(Log Sequence Number)来标记版本,LSN是日志空间中每条日志的结束点,用字节偏移量来表示。每个page有LSN,redo log也有LSN,Checkpoint也有LSN。可以通过命令show engine innodb status来观察:

  1. ---
  2. LOG
  3. ---
  4. Log sequence number 1039878815567
  5. Log flushed up to 1039878815567
  6. Pages flushed up to 1039878814486
  7. Last checkpoint at 1039878814486
  8. 0 pending log writes, 0 pending chkp writes
  9. 5469310 log i/o's done, 1.00 log i/o's/second
Checkpoint机制每次刷新多少页,从哪里取脏页,什么时间触发刷新?这些都是很复杂的。有两种Checkpoint,分别为:
  • Sharp Checkpoint
  • Fuzzy Checkpoint
Sharp Checkpoint发生在关闭数据库时,将所有脏页刷回磁盘。在运行时使用Fuzzy Checkpoint进行部分脏页的刷新。部分脏页刷新有以下几种:
  • Master Thread Checkpoint
  • FLUSH_LRU_LIST Checkpoint
  • Async/Sync Flush Checkpoint
  • Dirty Page too much Checkpoint
Master Thread Checkpoint Master Thread以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘。这个过程是异步的,不会阻塞查询线程。

Flush LRU List Checkpoint
InnoDB要保证LRU列表中有100左右空闲页可使用。在InnoDB1.1.X版本前,要检查LRU中是否有足够的页用于用户查询操作线程,如果没有,会将LRU列表尾端的页淘汰,如果被淘汰的页中有脏页,会强制执行Checkpoint刷回脏页数据到磁盘,显然这会阻塞用户查询线程。从InnoDB1.2.X版本开始,这个检查放到单独的Page Cleaner Thread中进行,并且用户可以通过innodb_lru_scan_depth控制LRU列表中可用页的数量,默认值为1024。

Async/Sync Flush Checkpoint
是指重做日志文件不可用时,需要强制将脏页列表中的一些页刷新回磁盘。这可以保证重做日志文件可循环使用。在InnoDB1.2.X版本之前,Async Flush Checkpoint会阻塞发现问题的用户查询线程,Sync Flush Checkpoint会阻塞所有查询线程。InnoDB1.2.X之后放到单独的Page Cleaner Thread。

Dirty Page Too Much Checkpoint
脏页数量太多时,InnoDB引擎会强制进行Checkpoint。目的还是为了保证缓冲池中有足够可用的空闲页。其可以通过参数
innodb_max_dirty_pages_pct来设置,默认为75%。

  1. (root@localhost)[(none)]> show variables like 'innodb_max_dirty_pages_pct';
  2. +----------------------------+-------+
  3. | Variable_name | Value |
  4. +----------------------------+-------+
  5. | innodb_max_dirty_pages_pct | 75 |
  6. +----------------------------+-------+
  7. 1 row in set (0.00 sec
以上是脏页刷新的几种触发机制,接下来,细说一下日志机制及其中第3点Async/Sync flush checkpoint原理。

Log及Checkpoint简介

Innodb的事务日志是指Redo log,简称Log,保存在日志文件ib_logfile*里面。Innodb还有另外一个日志Undo log,但Undo log是存放在共享表空间里面的(ibdata*文件)。

由于Log和Checkpoint紧密相关,因此将这两部分合在一起分析。

名词解释:LSN,日志序列号,Innodb的日志序列号是一个64位的整型。

Log写入

LSN实际上对应日志文件的偏移量,新的LSN=旧的LSN + 写入的日志大小。举例如下:

LSN=1G,日志文件大小总共为600M,本次写入512字节,则实际写入操作为:

| --- 求出偏移量:由于LSN数值远大于日志文件大小,因此通过取余方式,得到偏移量为400M;

| --- 写入日志:找到偏移400M的位置,写入512字节日志内容,下一个事务的LSN就是1000000512;

Checkpoint写入

Innodb实现了Fuzzy Checkpoint的机制,每次取到最老的脏页,然后确保此脏页对应的LSN之前的LSN都已经写入日志文件,再将此脏页的LSN作为Checkpoint点记录到日志文件,意思就是"此LSN之前的LSN对应的日志和数据都已经写入磁盘文件"。恢复数据文件的时候,Innodb扫描日志文件,当发现LSN小于Checkpoint对应的LSN,就认为恢复已经完成。

Checkpoint写入的位置在日志文件开头固定的偏移量处,即每次写Checkpoint都覆盖之前的Checkpoint信息。

Flush刷新流程及原理介绍

由于Checkpoint和日志紧密相关,将日志和Checkpoint一起说明,详细的实现机制如下:


如上图所示,Innodb的一条事务日志共经历4个阶段:

1) 创建阶段:事务创建一条日志;

2) 日志刷盘:日志写入到磁盘上的日志文件;

3) 数据刷盘:日志对应的脏页数据写入到磁盘上的数据文件;

4) 写CKP:日志被当作Checkpoint写入日志文件;


对应这4个阶段,系统记录了4个日志相关的信息,用于其它各种处理使用:

Log sequence number(LSN1):当前系统LSN最大值,新的事务日志LSN将在此基础上生成(LSN1+新日志的大小);

Log flushed up to(LSN2):当前已经写入日志文件的LSN;

Pages flushed up to(LSN3):当前最旧的脏页数据对应的LSN,写Checkpoint的时候直接将此LSN写入到日志文件;

Last checkpoint at(LSN4):当前已经写入Checkpoint的LSN;

对于系统来说,以上4个LSN是递减的,即: LSN1>=LSN2>=LSN3>=LSN4.

具体的样例如下(使用show engine innodb status \G命令查看)

概念计算含义Ckp ageLSN1- LSN4还没有做Checkpoint的日志范围,若Ckp age超过日志空间,说明被覆盖的日志(LSN1-LSN4-Log cap)对应日志和数据"可能"还没有刷到磁盘上Buf ageLSN1- LSN3还没有将脏页刷盘的日志的范围,若Buf age超过日志空间,说明被覆盖的日志(LSN1-LSN3-Log cap)对应数据"肯定"还没有刷到磁盘上Buf async日志空间大小 * 7/8强制将Buf age-Buf async的脏页刷盘,此时事务还可以继续执行,所以为async,对事务的执行速度没有直接影响(有间接影响,例如CPU和磁盘更忙了,事务的执行速度可能受到影响)Buf sync日志空间大小 * 15/16强制将2*(Buf age-Buf async)的脏页刷盘,此时事务停止执行,所以为sync,由于有大量的脏页刷盘,因此阻塞的时间比Ckp sync要长。Ckp async日志空间大小 * 31/32强制写Checkpoint,此时事务还可以继续执行,所以为async,对事务的执行速度没有影响(间接影响也不大,因为写Checkpoint的操作比较简单)Ckp sync日志空间大小 * 64/64强制写Checkpoint,此时事务停止执行,所以为sync,但由于写Checkpoint的操作比较简单,即使阻塞,时间也很短

当事务执行速度大于脏页刷盘速度时,Ckp age和Buf age会逐步增长,当达到async点的时候,强制进行脏页刷盘或者写Checkpoint,如果这样做还是赶不上事务执行的速度,则为了避免数据丢失,到达sync点的时候,会阻塞其它所有的事务,专门进行脏页刷盘或者写Checkpoint。

因此从理论上来说,只要事务执行速度大于脏页刷盘速度,最终都会触发日志保护机制,进而将事务阻塞,导致MySQL操作挂起。

由于写Checkpoint本身的操作相比写脏页要简单,耗费时间也要少得多,且Ckp sync点在Buf sync点之后,因此绝大部分的阻塞都是阻塞在了Buf sync点,这也是当事务阻塞的时候,IO很高的原因,因为这个时候在不断的刷脏页数据到磁盘。例如如下截图的日志显示了很多事务阻塞在了Buf sync点:

日志 数据 事务 文件 磁盘 阻塞 速度 大小 空间 强制 缓冲 机制 时候 时间 偏移 查询 线程 部分 影响 数据库 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 新华互联网科技学校 互联网科技有限公司经营范围 河南真二互联网科技有限公司 工业互联网科技新基建 金融科技 互联网金融 丰台科技园 互联网 亿人帮互联网科技 成都仁贤领冠互联网科技有限公司 青岛中康互联网医疗科技有限公司 新华互联网科技2019 北京大学互联网科技怎么样 互联网科技革命什么开始 搜狐科技互联网 互联网科技人工智能实验室 保险科技服务互联网营销体系 广东工业互联网大赛深圳学泰科技 张家口科技产业互联网平台 好易买互联网科技 互联网对科技影响 保山浩联互联网科技有限公司 瑰夏咖啡 耶加雪菲 深圳九邦互联网科技有限公司 互联网科技生活的内容 承德科技产业互联网发展 金融科技与互联网金融相同和不同 互联网方面的科技前沿 广州有谷有贝互联网科技有限公司 中国互联网公司的科技投入 互联网科技大佬云集
0