MySQL检查点机制 - CheckPoint

1、情景展现


思考一下这个场景:如果重做日志可以无限地增大,同时缓冲池也足够大,那么就没有必要将缓冲池中页的新版本刷新回磁盘,只需要将重做日志实时刷新到磁盘即可。因为当发生宕机时,完全可以通过重做日志来恢复整个数据库系统中的数据到宕机发生的时刻。

这需要两个前提条件:
(1)缓冲池可以缓存数据库中所有的数据;
(2)重做日志可以无限增大;
这两点正常情况下几乎不可实现,且衍生出来的另一严重问题:当数据库发生宕机时,需要通过日志恢复所有数据,非常耗时。

2、Checkpoint作用


  • 缩短数据库的恢复时间
    当数据库发生宕机时,数据库不需要重做所有的日志,因为 Checkpoint 之前的页都已经刷新回磁盘。数据库只需对 Checkpoint 后的重做日志进行恢复,这样就大大缩短了恢复的时间。
  • 缓冲池不够用时,将脏页刷新到磁盘
    当缓冲池不够用时,根据 LRU 算法会溢出最近最少使用的页,若此页为脏页,那么需要强制执行 Checkpoint ,将脏页也就是页的新版本刷回磁盘。
  • 重做日志不可用时,刷新脏页
    当重做日志出现不可用时,因为当前事务数据库系统对重做日志的设计都是循环使用的,并不是让其无限增大的。重做日志可以被重用的部分是指这些重做日志已经不再需要,当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分就可以被覆盖重用。如果重做日志还需要使用,那么必须强制 Checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置。

对于 InnoDB 存储引擎而言,是通过 LSN(Log Sequence Number)来标记版本的。Checkpoint 发生的时间、条件及脏页的选择等都非常复杂。然而 Checkpoint 所做的事情无外乎是将缓冲池中的脏页刷回到磁盘,不同之处在于每次刷新多少页到磁盘,每次从哪里取脏页,以及什么时间触发Checkpoint

3、Checkpoint分类


  • sharp checkpoint
    在关闭数据库的时候,将buffer pool中的脏页全部刷新到磁盘中。
  • fuzzy checkpoint
    数据库正常运行时,在不同的时机,将部分脏页写入磁盘。仅部分刷新也是为了避免一次刷新全部的脏页造成的性能问题。

4、Fuzzy Checkpoint分类

4.1、Master Thread Checkpoint


在Master Thread中,会以每秒或者每10秒一次的频率,将部分脏页从内存中刷新到磁盘,这个过程是异步的。正常的用户线程对数据的操作不会被阻塞。

4.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 列表尾端的页面。
MySQL检查点机制 - CheckPoint_第1张图片

4.3、Async / Sync Flush Checkpoint


Async / Sync Flush checkpoint 是在单独的 page cleaner 线程中执行的。Async / Sync Flush checkpoint 发生在重做日志不可用的时候,将 buffer pool 中的一部分脏页刷新到磁盘中。在脏页写入磁盘之后,事务对应的重做日志也就可以释放了。关于 redo_log 文件的的大小,可以通过innodb_log_file_size来配置。
MySQL检查点机制 - CheckPoint_第2张图片
对于是执行 Async Flush checkpoint 还是 Sync Flush checkpoint,由checkpoint_ageasync_water_marksync_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
  • checkpoint_age < async_water_mark
    无需执行Flush checkpoint。也就是说,redo log 剩余空间超过25%的时候,无需执行Async / Sync Flush checkpoint。
  • async_water_mark < checkpoint_age < sync_water_mark
    执行Async Flush checkpoint。也就是说,redo log 剩余空间不足25%,但是大于10%的时候,执行 Async Flush checkpoint,刷新到满足条件1。
  • checkpoint_age > sync_water_mark
    执行sync Flush checkpoint。也就是说,redo log 剩余空间不足10%的时候,执行Sync Flush checkpoint,刷新到满足条件1。在mysql 5.6之后,不管是Async Flush checkpoint还是Sync Flush checkpoint,都不会阻塞用户的查询进程。

由于磁盘是一种相对较慢的存储设备,内存与磁盘的交互是一个相对较慢的过程。所以应该将 innodb_log_file_size 定义为一个相对较大的值。正常情况下,由前面两种 checkpoint 刷新脏页到磁盘,在前面两种 checkpoint 刷新脏页到磁盘之后,脏页对应的 redo log 空间随即释放,一般不会发生Async / Sync Flush checkpoint。同时也要意识到,为了避免频繁低发生Async / Sync Flush checkpoint,也应该将 innodb_log_file_size 配置的相对较大一些

4.4、Dirty Page too much


Dirty Page too much Checkpoint是在Master Thread 线程中每秒一次的频率实现的。Dirty Page too much 意味着buffer pool中的脏页过多,执行checkpoint脏页刷入磁盘,保证buffer pool中有足够的可用页面

Dirty Page由innodb_max_dirty_pages_pct配置,默认值在InnoDB 1.0之前是90%,之后是75%。

MySQL检查点机制 - CheckPoint_第3张图片

你可能感兴趣的:(#,MySQL,数据库,mysql)