Checkpoint机制
最近在学习MySQL的底层,内容来自于Mysql技术内幕书籍和自己的理解,所以写了一个关于MySQL技术内幕专栏,有兴趣可以看看
1.CheckPoint出现的原因
- 之前的博客有讲到当执行DML操作时,如UPDATE,Delete改变了页中的记录,此时的页还没有刷新回磁盘,只是在缓冲池中被修改了。这样的页称为脏页。
- CheckPoint所做的事情无非就是将缓冲池的脏页刷新回磁盘,但是他的触发机制和脏页的选择以及版本的记录都是很复杂的,这也是为了解决以下的问题。
1.1.1 原因一:缓冲池必须进行脏页刷新
- 试想如果缓冲池中的内存足够大,可以缓冲数据库中的所有数据,那么我们根本不需要将脏页刷新回磁盘,这样会大大增加了数据库系统的高效性!
- 但是缓冲池是无法无法缓存数据库中所有的数据,所以必须将脏页进行刷新回磁盘。如果每次一个页发生变化,就将新页的版本刷新到磁盘中,这个开销是非常大的。
- 所以这是第一个问题,需要一个比较高效的管理脏页刷新的触发机制控制。
1.1.2 原因二:重做日志不可以无限增大
- 如果从缓冲池中将脏页刷新回磁盘的过程中发生了宕机,那么数据就无法恢复了。
- 所以为了避免数据丢失的问题,当前事务数据库系统普遍采用了Write Ahead Log策略:当事务提交时,先写日志,再修改页。这样如果发生数据丢失,就可以通过日志来恢复。
- 如果重做日志可以无限增大的话,那么就意味着我们每次宕机时就可以通过日志去恢复数据了。但是有一个情况需要考虑:如果数据库运行了几年之久,此时宕机的话,那么数据恢复的时间和代价是非常大的。
- 但是实际上重做日志不是无限增大的,而是循环使用的,也就是说重做日志会在一定机制下会覆盖之前日志,这样的话有时候在宕机进行数据恢复的时候日志时不可用的。
- 所以这是第二个问题:使用日志进行数据恢复的时间很长,并且有时日志不可用,所以需要CheckPoint来解决
2.Checkpoint解决的问题
综上所述,Checkpoint技术的出现就是为了解决以下问题的:
- 缩短数据库的恢复时间
- 缓冲池不够用时,将脏页刷新回磁盘
- 重做日志不可用时,刷新脏页
当数据库发生宕机时,数据库不需要重做所有的日志,因为上次CheckPoint之前的页都已经刷新回磁盘了,只需要将数据库恢复到上次CheckPoint的状态就可以!
3.CheckPoint机制
在理解CheckPoint机制之前必须对InnoDB存储引擎的体系和内存池的管理机制有一定的了解:
InnoDB存储引擎体系架构——详解
InnoDB存储引擎之缓冲池技术(内存管理)——详解
3.1 版本控制
- CheckPoint所做的事情无非就是将缓冲池的脏页刷新回磁盘,并且每次会记录版本。这样当数据库宕机时,就知道上次CheckPoint的地方在哪,只要恢复到那个状态就行
- 在InnoDB存储引擎中,其实通过LSN来标记版本的。LSN是8字节的数字,每个页中有LSN,重做日志中也有LSN,Checkpoint也有LSN。
在InnoDB存储引擎中,Checkpoint分为两种:Sharp Checkpoint 和 Fuzzy Checkpoint
3.2 Sharp CheckPoint
- Sharp CheckPoint 发生在数据库关闭时,将所有的脏页全部刷新回磁盘,这是默认的工作方式
3.3 Fuzzy Checkpoint
这里作者对Fuzzy Checkpoint可能触发的情况做了概括:
- Master Thread Checkpoint
- FLUSH_LRU_LIST Checkpoint
- Async/Sync Flush Checkpoint
- Dirty Page too much Checkpoint
3.3.1 Master Thread Checkpoint
对Master Thread不清楚的朋友可以看这篇博客:
InnoDB存储引擎之Master Thread底层实现——详解
- Master Thread中会有每一秒的操作和每十秒的操作,会将一定的脏页刷新回磁盘
3.3.2 FLUSH_LRU_LIST Checkpoint
- InnoDB存储引擎中需要保证LRU列表中需要有差不多100个空闲页可以使用。如果每次检查LRU列表中没有足够的可用空间,就会移除尾端的页,如果这些页有脏页的话,也会进行脏页刷新
3.3.3 Async/Sync Flush Checkpoint
- 当重做日志文件不可用的情况出现时,也就是重做日志文件满了,需要进行循环使用的时候,此时也会触发Checkpoint
3.3.4 Dirty Page too much Checkpoint
- 当脏页数量太多的时候也会触发Checkpoint
4.总结
- 总的来说CheckPoint所做的事情无非就是将缓冲池的脏页刷新回磁盘,只是他的触发机制和脏页的选择有一定的复杂性,以及版本的控制等
- 但是这种复杂性也是为了提高InnoDB存储引擎的性能,去解决之前到的问题,例如:缩短数据库恢复时间等