InnoDB脏页刷新机制Checkpoint

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

  • 服务器内存有限,缓冲池不够用,无法缓存全部数据
  • 重做日志无限增大成本要求太高
  • 宕机时如果重做全部日志恢复时间过长

事实上,当数据库宕机时,数据库不需要重做所有的日志,只需要执行上次刷入点之后的日志。这个点就叫做Checkpoint,它解决了以上的问题:

  • 缩短数据库恢复时间
  • 缓冲池不够用时,将脏页刷新到磁盘
  • 重做日志不可用时,刷新脏页

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

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

1--- 2LOG 3--- 4Log sequence number 11102619599 5Log flushed up to 11102618636 6Last checkpoint at 11102606319 70 pending log writes, 0 pending chkp writes 815416290 log i/o's done, 12.32 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来设置:

1mysql> show variables like 'innodb_max_dirty_pages_pct'; 2+----------------------------+-------+ 3| Variable_name | Value | 4+----------------------------+-------+ 5| innodb_max_dirty_pages_pct | 90 | 6+----------------------------+-------+
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

MySQL 日志(redo log 和 undo log) 都是什么鬼东西!?

innodb事务日志包括redolog和undolog。redolog是重做日志,提供前滚操作,undolog是回滚日志,提供回滚操作。undolog不是redolog的逆向过程,其实它们都算是用来恢复的日志:1.redolog通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数

InnoDB脏页刷新机制Checkpoint - HelloWorld