Mysql 的checkpoint
1、Checkpoint作用
- 缩短数据库的恢复时间
当数据库发生宕机时,数据库不需要重做所有的日志,因为 Checkpoint 之前的页都已经刷新回磁盘。数据库只需对 Checkpoint 后的重做日志进行恢复,这样就大大缩短了恢复的时间。 - 缓冲池不够用时,将脏页刷新到磁盘
当缓冲池不够用时,根据 LRU 算法会溢出最近最少使用的页,若此页为脏页,那么需要强制执行 Checkpoint ,将脏页也就是页的新版本刷回磁盘。 - 重做日志不可用时,刷新脏页
当重做日志出现不可用时,因为当前事务数据库系统对重做日志的设计都是循环使用的,并不是让其无限增大的。重做日志可以被重用的部分是指这些重做日志已经不再需要,当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分就可以被覆盖重用。如果重做日志还需要使用,那么必须强制 Checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置。
对于 InnoDB 存储引擎而言,是通过 LSN(Log Sequence Number)来标记版本的。Checkpoint 发生的时间、条件及脏页的选择等都非常复杂。然而 Checkpoint 所做的事情无外乎是将缓冲池中的脏页刷回到磁盘,不同之处在于每次刷新多少页到磁盘,每次从哪里取脏页,以及什么时间触发Checkpoint。
2、Checkpoint分类
sharp checkpoint
在关闭数据库的时候,将buffer pool中的脏页全部刷新到磁盘中。
fuzzy checkpoint
数据库正常运行时,在不同的时机,将部分脏页写入磁盘。仅部分刷新也是为了避免一次刷新全部的脏页造成的性能问题。
3、Fuzzy Checkpoint分类
3.1、Master Thread Checkpoint
在Master Thread中,会以每秒或者每10秒一次的频率,将部分脏页从内存中刷新到磁盘,这个过程是异步的。正常的用户线程对数据的操作不会被阻塞。
3.2、FLUSH_LRU_LIST Checkpoint
FLUSH_LRU_LIST Checkpoint 是在单独的 page cleaner 线程中执行的。MySQL 对缓存的管理是通过 buffer pool 中的 LRU 列表实现的,LRU 空闲列表中要保留一定数量的空闲页面,来保证 buffer pool 中有足够的空闲页面来相应外界对数据库的请求。当这个空间页面数量不足的时候,发生FLUSH_LRU_LIST checkpoint。空闲页的数量由innodb_lru_scan_depth参数表来控制的,因此在空闲列表页面数量少于配置的值的时候,会发生 checkpoint,剔除部分 LRU 列表尾端的页面。
3.3、Async / Sync Flush Checkpoint
Async / Sync Flush checkpoint 是在单独的 page cleaner 线程中执行的。Async / Sync Flush checkpoint 发生在重做日志不可用的时候,将 buffer pool 中的一部分脏页刷新到磁盘中。在脏页写入磁盘之后,事务对应的重做日志也就可以释放了。关于 redo_log 文件的的大小,可以通过innodb_log_file_size来配置。
对于是执行 Async Flush checkpoint 还是 Sync Flush checkpoint,由checkpoint_age、async_water_mark和sync_water_mark来决定:
即checkpoint_age等于 最新的lsn 减去 已经刷新到磁盘的lsn的值
checkpoint_age = redo_lsn - checkpoint_lsn
async_water_mark = 0.75 * innodb_log_file_size
sync_water_mark = 0.9 * innodb_log_file_size