2.4 InnoDB存储引擎 - CheckPoint 技术

 前面提到缓冲池的设计是为了协调CPU速度和磁盘速度的鸿沟。如果一条DML语句改变了页中的记录,那么此页就是脏的,即缓冲池中的页的版本比磁盘的新。数据库需要将新版本的页刷回到磁盘。


再提一点,当前事务数据库系统普遍采用的都是 Write Ahead Log 策略,即当事务提交时,先写重做日志,再修改页。当由于发生当时而导致数据丢失时,通过重做日志来完成数据的恢复。这也是事务中持久性的要求。

 

思考一个场景:

如果重做日志可以无限增大,同时缓冲池也足够大,能够缓冲所有数据库的数据,那么是不需要将缓冲池的页的新版本刷回到磁盘的。因为宕机时,完全可以通过重做日志来恢复整个数据库系统中的数据到宕机发生的时刻,但是有两个前提条件:

  1. 缓冲池足够大
  2. 重做日志可以无限增大
  3. 宕机后的数据库的恢复时间,重做日志越大,恢复的时间越久。

涉及到的CheckPoint技术,主要是用来解决: 1. 缩短数据库的恢复时间。2. 缓冲池不够用时,将脏页刷新到磁盘。3. 重做日志不可用时,刷新脏页。CheckPoint 的出现:当数据库发生宕机时,数据库不需要重做所有的日志,因为CheckPoint之前的页已经刷新回磁盘。故数据库只需要对CheckPoint 后的重做日志进行恢复。这样就大大缩短了恢复的时间。

 

此外,当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,那么需要强制执行CheckPoint,将脏页,也就是最新版本的页刷新回磁盘。

 

重做日志出现不可用的情况是因为当前事务数据库系统对重做日志的设计是可循环使用的。重做日志可以被重用的部分是指这些日志已经不需要了,即当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分可以被覆盖重用。若此时,重做日志还需要使用,那么必须强制执行 CheckPoint,将缓冲池中的页至少刷新到当前重做日志的位置。

 

对InnoDB 而言,其是通过LSN来标记版本的(Log Sequence Number),而LSN是8个字节的数字,每个页有LSN,重做日志也有,CheckPoint也有,可以通过 Show engine InnoDB status来查看。

 

在InnoDB中,CheckPoint发生的时间、条件及脏页的选择都非常复杂。而CheckPoint所做的事情,也无外乎是将缓冲池中的脏页刷回磁盘,不同之处是每次刷新多少、从哪里的读取脏页、以及什么时间出发 CheckPoint。

 

InnoDB 内部有两种 CheckPoint,分别是:

1. Sharp CheckPoint : 数据库关闭时,将所有脏页刷新到磁盘,默认的工作方式。但如果运行时,也使用Sharp方式,会对数据库的可用性造成很大影响。

 

2. Fuzzy CheckPoint :每次只刷新一部分脏页

  Fuzzy CheckPoint 的触发实际:

  • Master ThreadCheckPoint
    • master thread 会以一定的频率从缓冲池的脏页列表中刷新一定比例的页会磁盘,这个过程是异步的,不会阻塞查询
  • Flush_lru_list checkPoint
    • LRU列表要保证有差不多100个空闲页可用。
    • Page Cleaner线程中,会检查LRU列表中是否有足够的可用空间,没有的话,则移除LRU尾部的页,如果这些页中有脏页,则需要CheckPoint
  • Async/Sync Flush CheckPoint
    • 重做日志不可用的情况下,需要强制将一些页刷回到磁盘,而此时脏页是从脏页列表中选取的。若将已经写入到重做日志的LSN记为redo_lsn
    • 用来保证重做日志的循环使用。MySQL 5.6 以后,该操作移到了 Page Cleaner  Thread 中,故不会阻塞用户的查询
  • Dirty Page too much CheckPoint
    • 总的来说,是为了保证缓冲池中有足够可用的页。InnoDB—max_dirty_pages_pct 标识当缓冲池中脏页的数量占据 75%时,强制 CheckPoint,刷新部分脏页回磁盘。

 

posted @ 2021-08-27 15:22  傑0327  阅读(62)  评论(0编辑  收藏  举报