Mysql中Checkpoint技术

94 阅读4分钟

image.png

都知道缓冲池的出现就是为了解决CPU与磁盘速度之间的鸿沟,免得我们在读写数据库时还需要进行磁盘IO操作。有了缓冲池后,所有的页操作首先都是在缓冲池内完成的。

如一个DML语句,进行数据update或delete 操作时,此时改变了缓冲池页中的记录,此时因为缓冲池页的数据比磁盘的新,此时的页就叫做脏页。

Checkpoint技术就是将缓存池中脏页在某个时间点刷回到磁盘的操作。

我们从为什么需要checkpoint开始探索。

1、为什么需要Checkpoint?

我们都知道,mysql数据库的主要存储空间是磁盘,而上述的缓冲池是内存,那么必然有一个从内存到磁盘的过程。当然,这是从结果出发的,那如果有两个条件:

  • 缓冲池可以缓存数据库的所有数据
  • 重做日志可以无限大(Write Ahead Log:在缓冲池中先写重做日志,再修改页,保证持久化要求)

如果满足这两个要求似乎就可以不需要Checkpoint了,但是缓存所有数据只有项目初期能够实现,随着用户量的增大,数据库的容量必然增大。而重做日志的作用是防止数据库宕机后重启,保证数据的完整,不说无限大所需要的运维成本,就数据量很大,重启所需要的时间就非常久,这是很多项目不能接受的。

2、Checkpoint的作用 Checkpoint能够解决以下问题:

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

缩短数据库恢复时间不难理解,因为恢复时不需要恢复全部的重写日志(逻辑上的全部),只需要恢复checkpoint之后的就行。

当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,则需要强制执行checkpoint,将脏页刷入磁盘。

mysql重做日志不是无限大的,它是循环使用的,若重做日志被覆盖(被重用的已经不需要的日志),如果需要继续使用重做日志必须强制checkpoint,将缓冲池中的页至少刷新到重做日志的位置。

InnoDB存储引擎内部为我们提供了两种Checkpoint:

  • Sharp Checkpoint

    发生在数据库关闭时将所有的脏页都刷新回磁盘,这是默认的工作方式,参数innodb_fast_shutdown=1

  • Fuzzy Checkpoint

    InnoDB存储引擎内部使用这种模式,只刷新一部分脏页,而不是刷新所有的脏页回磁盘

FuzzyCheckpoint发生的情况

  • Master Thread Checkpoint

    差不多以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘。

    这个过程是异步的,即此时InnoDB存储引擎可以进行其他的操作,用户查询线程不会阻塞

  • FLUSH_LRU_LIST Checkpoint

    因为LRU列表要保证一定数量的空闲页可被使用,所以如果不够会从尾部移除页,如果移除的页有脏页,就会进行此Checkpoint。

    5.6版本后,这个Checkpoint放在了一个单独的Page Cleaner线程中进行,并且用户可以通过参数innodb_lru_scan_depth控制LRU列表中可用页的数量,该值默认为1024

  • Async/Sync Flush Checkpoint

    指的是redo log文件不可用的情况,这时需要强制将一些页刷新回磁盘,而此时脏页是从脏页列表中选取的

    5.6版本后不会阻塞用户查询

  • Dirty Page too much Checkpoint 即脏页的数量太多,导致InnoDB存储引擎强制进行Checkpoint。

    其目的总的来说还是为了保证缓冲池中有足够可用的页。

    其可由参数innodb_max_dirty_pages_pct控制,比如该值为75,表示当缓冲池中脏页占据75%时,强制进行CheckPoint

参考文档:《MySQL技术内幕 InnoDB存储引擎 第2版》