InnoDB(2.2):体系架构之Checkpoint技术

前一面一篇粗略了解InnoDB体系架构里面的缓冲池,下面详细认识以下缓冲池里面的技术和线程执行过程。

Checkpoint技术

缓冲池的目的是减少数据库访问磁盘的次数,提高效率的,页的操作一般都会先在缓冲池完成(读也是要先访问缓冲池看有没有该页,才去磁盘去找),前面也提到过脏页的出现,如果数据库执行了一条DML语句,比如删除或修改页数据,也会先修改缓冲池中的页,然后后面再交给IO Thread去将页刷新到磁盘中,此时就会有一个时间差,再这个时间差里,还没刷新到磁盘中的页就称为脏页(因为数据不对应)。

但是,页一发生变化就进行刷新,这个开销是很大的,同时,如果刷新到数据库时,突然发生宕机,数据就恢复不了(数据的恢复要依靠日志来恢复,而日志也不是马上刷新的,前面提到过三种情况才会刷新重做日志缓冲到磁盘),为了避免发生数据丢失问题,当前事务数据库系统普遍采用了Write Ahead log策略

Write Ahead log策略

这种策略是指,当事务提交时,要先重做日志,然后再修改页,如果由于宕机发生修改页失败,那么可以通过日志来完成数据的恢复,这也是事务的ACID里面的D属性(Durability 持久性)。

假设重做日志可以无限增大,而且缓冲池足够大,可以缓冲所有数据库的数据,那么就不必将缓冲池中的页刷新回磁盘了,只需要操作缓冲池就行,当发生宕机后,可以通过重做日志来恢复整个数据库系统到宕机发生的时刻。但这两个条件都很苛刻。

即使满足前面这两个条件,但如果对于重做日志很大,宕机后数据库的恢复时间要很久,此时恢复的代价也是非常大的,所以此时就有了checkpoint技术(检查点)

checkpoint技术主要优化如下

  • 缩短数据库的恢复时间
  • 缓冲池不够用时,将脏页刷新到磁盘
  • 重做日志不可用时,刷新脏页

当数据库发生宕机时,数据库不需要重新去重做所有的日志,因为checkpoint之前的页都是已经刷新到磁盘上了,数据库只需要对checkpoint后的重做日志进行恢复,这样就大大缩短了数据库恢复时间。

除此之外,如果缓冲池不够用,LRU列表会溢出old区里面的页(最少使用的页),如果此页是脏页,就会发生数据丢失,所以,发生缓冲池不够用时,若脏页要被溢出,就会被强制执行checkpoint,将脏页刷新到磁盘。

重做日志并不是可以无限增大的,只不过可以重用那些不需要的空间(是指那些不再需要的重做日志),当数据库发生宕机时,如果数据库根据日志来恢复数据时,发现重做日志的某部分不需要使用,那么这部分可能就会被释放,来覆盖重用(这些数据一般都是已经被写入磁盘永久保存了,不需要日志来恢复),若该重做日志还要继续使用,那么必须强制执行checkpoint,将缓冲池的页刷新到当前重做日志的位置。(即重做日志重用了某些不需要使用的部分,此时需要重做日志缓冲池对重做日志进行刷新,来覆盖那些不需要的部分日志)。

InnoDB通过LSN(log Sequence Number->日志序列号,表示事务写入到日志的字节总量)来标记版本的,LSN是一个8个字节的数字,每个页都有LSN,重做日志中也有LSN,CheckPoint也有LSN。

//查看InnoDB的LSN
SHOW ENGINE INNODB STATUS;

CheckPoint所做的事情无外乎是将缓冲池的脏页刷新回磁盘中,不过脏页的选择、CheckPoint发生的时间是比较负责的。重点在于,每次要刷新多少页到磁盘,又是从哪里获取脏页,以及什么时间触发CheckPoint。

InnoDB存储引擎内部,有两种Checkpoint,分别为:

  • Sharp Checkpoint
  • Fuzzy Checkpoint
Sharop Checkpoint

Sharp Checkpoint是发生在数据库关闭时将所有的脏页都刷新回磁盘中,这也是默认的工作方式,即参数innodb_fast_shutdown=1。

Fuzzy Checkpoint

在InnoDB存储引擎内部是使用Fuzzy Checkpoint进行页的刷新,即在数据库运行时,使用的是Fuzzy Checkpoint,即只会刷新部分脏页,而不是刷新所有的脏页回磁盘

Fuzzy Checkpoint大概在以下几种情况会发生

  1. Master Thread Checkpoint
  2. FLUSH_LRU_LIST Checkpoint
  3. Async/Sync Flush Checkpoint
  4. Dirty Page too much Checkpoint
Master Thread CheckPoint

Master Thread Checkpoint是在Master Thread中发生的,Master Thread会以差不多每秒或每十秒从缓冲池中刷新一定比例的页会磁盘,这个过程是异步的,即不会阻塞其他操作,比如用户查询线程。

Flush_LRU_LIST_Checkpoint

FLUSH_LRU_LIST Checkpoint是用来保证缓冲池中的LRU列表中需要差不多100个空闲页可供使用。

在InnoDB1.1.X版本之前,需要检查LRU列表中是否有足够的可用空间,这个操作是发生在用户查询线程中的,这显然会对用户查询线程造成阻塞影响,降低了效率,倘若发现LRU列表不足100个空闲页时,那么InnoDB存储引擎会将LRU列表尾端的页移除(old区),如果发现移除的页中存在脏页,那么就要进行checkpoint,将脏页刷新回磁盘中,因为这些页是LRU列表中的,所以称为FLUSH_LRU_LIST Checkpoint。

但从InnoDB1.2.X版本开始(即MySQL5.6版本),这个检查就被单独放在Page Cleaner线程中进行,用户可以通过控制参数innodb_lru_scan_depth控制LRU列表里面可用页的数量,现在默认为1024。

SHOW VARIABLES LIKE 'innodb_lru_scan_depth';

在这里插入图片描述

Async/Sync Flush Checkpoint

Async/Sync Flush Checkpoint指的是重做日志文件不可用的情况,这是要像使用回不可用的重做日志,就要强制将一些页刷新回磁盘,此时脏页是从脏页列表中选取的

若将已经重做日志中已经有的LSN记为redo_lsn,将要刷新回磁盘的页的总LSN记为checkpoint_lsn,定义一个check_point_age,定义如下

check_point_age = redo_lsn - checkpoint_lsn

这里可以将redo_lsn可以理解成当前磁盘上的重做日志的日志数量,checkpoint_lsn理解成释放掉不要的部分的重做日志的日志数量,那么两者相减,就得到了释放掉不要的部分重做日志的日志数量。

然后再定义以下的变量

async_water_mark = 75% * total_redo_log_file_size

sync_water_mark = 90% * total_redo_log_file_size

举个栗子,假如数据库中的每个重做日志的大小为1GB,(注意这里是日志文件大小,并不是lsn)并且里面有两个重做日志文件,则重做日志文件的总大小为2GB,即total_redo_log_file_size = 2GB。所以很容易得出async_water_mark = 1.5GB,sync_water_mark等于2GB。

  • 当check_point_age < async_water_mark时,是不会进行刷新页的
  • 当async_water_mark < check_point_age < sync_water_mark时,触发Async Flush Checkpoint会从脏页队列(Flush列)中刷新足够的页回磁盘,直到满足上面那个条件后,停止刷新
  • 当check_point_age > sync_water_mark时,也是如此,触发Sync Flush Checkpoint,从脏页队列中刷新足够的列回磁盘,直到满足上面条件后停止刷新。

可见,Async/Sync Flush Checkpoint是为了保护重做日志的循环使用的可用性(只有释放掉不要的部分满足一定大小才可以进行刷新)

同样的,在InnoDB1.2.X版本前,Async Flush Checkpoint会阻塞发现问题的用户查询线程,但Sync Flush Checkpoint会阻塞所有用户的查询线程,两者都要等待刷新完成,才可以继续使用

但从InnoDB1.2.X版本后(即MySQL5.6),这部分的刷新也被放到了Page Cleaner Thread中执行,并不会影响用户的查询线程。

Dirty Page too much

从名字就可以看出,当脏页数量太多时,InnoDB会强制进行CheckPoint,其目的来说,也是为了保证缓冲池中有足够的页可以使用(因为脏页不可以被随便替换掉,必须刷新才能被LRU列表替换),可以由参数innodb_max_dirty_pages_pct控制,默认为90。
在这里插入图片描述
当缓冲池的数量占据90%时,就会强制进行checkpoint,刷新一部分的脏页到磁盘。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值