深入了解Mysql【七】InnoDB脏页刷新机制Checkpoint与doublewrite
缓冲池的设计目的是为了协调CPU速度与磁盘速度的鸿沟。页的操作都在在缓冲池中完成的。如果一条DML语句,如Update或者Delete改变了页中的记录,那么此时页是脏的,即缓冲池中的页的版本比磁盘的要新。数据库需要将最新版本的页刷新到磁盘。
为了避免数据的丢失,事务数据库系统采用Write Ahead Log策略,事务提交时,先写重做日志,再修改页,这样,当发生宕机是,可以用重做日志来恢复数据。
如果要用重做日志来恢复所有的数据,有两个条件:
- 缓冲池可以存储所有的数据
- 重做日志无限大
显然,上面两个都不能达到,所以产生了Checkpoint技术。
1、Checkpoint作用
- 缩短数据库恢复时间
- 缓冲池不够用时,将脏页刷新到磁盘
- 重做日志不可用时,刷新脏页
当数据库发生宕机的时候,数据库只需要将Checkpoint后的重做日志进行恢复。
2、CheckPoint类型
InnoDB存储引擎有两种CheckPoint:
- Sharp Checkpoint
数据库关闭时触发,将所有的脏页刷新到磁盘。 - Fuzzy Checkpoint
刷新部分脏页。
3、Fuzzy Checkpoint的触发时机
3.1、Master Thread Checkpoint
以固定频率从缓冲池的脏页列表中刷新一定比例的页回磁盘。
3.2、FLUSH_LRU_LIST Checkpoint
Page Cleaner Thread 检查LRU列表中是否有足够多的空闲页,
若不够,则会删除LRU队列尾端的页,如果其中有脏页,则刷新到磁盘。
3.3、Async/Sync Flush Checkpoint
当重做日志不可用时,强制刷新脏页列表中的脏页。
3.4、Dirty Page too much Checkpoint
脏页数量太多时,InnoDB引擎强制刷新,以保证缓冲池中有足够多的页。
4、Double Write(两次写)
当数据库宕机时,可能InnoDB引擎正在将某个页写到表中,而只写了一部分,则放生部分写失效。
通过Double Write技术,可以给InnoDB引擎带来数据页的可靠性。
doublewrite由两部分组成:内存中的doublewrite buffer和磁盘上的共享表空间中的连续页。
在对缓冲池的脏页进行刷新时,并不直接写入磁盘,而是通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer分两次顺序的写入共享表空间的物理磁盘,然后马上调用fsync函数,同步磁盘,避免缓冲写带来的问题。在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中。是否开启doublewrite还需要看具体情况。
参考
《MySQL技术内幕:InnoDB存储引擎 第二版》