Checkpoint技术

缓冲池的设计目的为了协调CPU速度与磁盘速度的鸿沟。因此页的操作首先都是在

缓冲池中完成的。如果一条DML语句,如UpdateDelete改变了页中的记录,那么

此时页是脏的,即缓冲池中的页的版本要比磁盘的新。数据库需要将新版本的页从

缓冲池刷新到磁盘。

Write Ahead Log

倘若每次一个页发生变化,就将新页的版本刷新到磁盘,那么这个开销是非常大的。

若热点数据集中在某几个页中,那么数据库的性能将变得非常差。同时,如果在从

缓冲池将页的新版本刷新到磁盘时发生宕机,那么数据就不能恢复了。为了避免发生

数据丢失的问题,当前事务数据库系统普遍采用Write Ahead Log策略,即当事务提交时,

先写重做日志,再修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成

数据的恢复。这也是事务ACIDD(持久性)的要求。

Checkpoint解决的问题

假设重做日志可以无限增大,同时缓冲池也足够大,能缓冲数据库的所有数据,那么是

不需要将缓冲池中页的新版本刷新回磁盘的。

因为宕机时完全可以通过重做日志恢复整个数据库系统的数据。

假设数据库运行了很长时间,重做时的时间也会很长。

但这需要两个条件

  • 缓冲池可以缓存所有数据库中的数据
  • 重做日志可以无限增大

因此Checkpoint(检查点)技术的目的是解决一下几个问题

  • 缩短数据库的恢复时间

    当数据库发生宕机时,数据库不需要重做所有日志,

    只需对checkpoint后的日志进行恢复即可。

  • 缓冲池不够用时,将脏页刷新回磁盘

    当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,

    如果该页是脏页,那么需要强制执行checkpoint

  • 重做日志不可用时,刷新脏页

    重做日志的设计是可以循环使用的,不需要的日志是可以覆盖的。

    当要覆盖的日志是需要的时,就必须强制产生checkpoint,

    将缓冲池中的页至少刷新到当前重做日志的位置。

第三点不大明确

InnoDB checkpoint 的实现

对于 InnoDB存储引擎而言,其是通过LSNLog Sequence Number)来标记版本的。

LSN是8字节的数字,其单位是字节。每个页有LSN,重做日志有LSNcheckpoint

也有LSN

InnoDB存储引擎内部有两种checkpoint分别为:

  • Sharp Checkpoint
  • Fuzzy Checkpoint

Sharp Checkpoint发生在数据库关闭时将所有的脏页都刷新会磁盘,这是默认的工作方式,

即参数innodb_fast_shutdown=1

若数据库在运行时也使用Sharp Checkpoint,那么数据库性能会受很大影响。

故在InnoDB存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只刷新一部分脏页,

而不是刷新所有的脏页回磁盘。

几种发生Fuzzy Checkpoint的情况
  • Master Thread Checkpoint

    以一定频率将脏页刷新到磁盘中。

  • FLUSH_LRU_LIST Checkpoint

    InnoDB存储引擎需要保证LRU列表中需要有差不多100个空闲页可供使用,

    若没有足够的空闲页,则需要清除LRU列表,若清除的页中含脏页,则需要

    刷新到磁盘。

    InnoDB 1.2.x版本开始,这个操作被放在Page Cleaner Thread线程中。

  • Async/Sync Flush Checkpoint

    指重做日志不可用的情况,需要强制将一些页刷新会磁盘。

    缓冲池中的页被刷到磁盘,对应的重做日志就可以被覆盖了。

  • Dirty Page too much Checkpoint

    脏页数量太多,导致InnoDB存储引擎强制进行checkpoint。

    通过innodb_max_dirty_pages_pct控制,值为75时,表示

    当缓冲池中脏页的数量占据75%时,强制进行checkpoint。