MySQL InnoDB Checkpoint技术

脏页

  • 众所周知,在计算机的世界里,很多技术都是为了解决一个问题,即快速设备和慢速设备速度不匹配的问题。比如数据库PoolBuffer(缓冲池)的设计目的为了协调CPU速度与磁盘速度的鸿沟。当数据库进行更新操作时,首先先更新PoolBuffer,这是产生了所谓的脏页,即缓冲池中的页的版本要比磁盘的新。

WAL

  • PoolBuffer是在内存中开辟的空间,当机器遇到关机,重启等情况数据会丢失,所以需要将数据刷新到磁盘。但是每次一个页发生变化,就将新页的版本刷新到磁盘,那么这个开销是非常大的。若热点数据集中在某几个页中,那么数据库的性能将变得非常差。当前事务数据库系统普遍都采用了Write Ahead Log策略,即当事务提交时,先写重做日志,再修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成数据的恢复。

  • 如果缓冲区和重做日志可以无限增大,PoolBuffer的数据是否可以不持久化到磁盘?这里有2个前提:

  • 第一缓冲区无限大,缓冲区是内存空间,生产环境内存的空间很难无限扩展。

  • 第二日志空间理论上是可以无限扩展的,但是过大的日志会导致一个问题在重启时恢复的时间过长,并且不断增长的日志空间会给运维带来不便,可能触发磁盘空间的阈值。

Checkpoint技术

  • 有上面的分析可知,脏页的数据是需要持久化到磁盘的,但是有不能每次改变都刷新,Checkpoint技术就是解决刷新策略的一个办法。Checkpoint主要解决了如下3个问题:
  • 缩短数据库的恢复时间;
  • 缓冲池不够用时,将脏页刷新到磁盘;
  • 重做日志不可用时,刷新脏页;
缩短恢复时间
  • 当数据库发生宕机时,数据库不需要重做所有的日志,因为Checkpoint之前的页都已经刷新回磁盘。故数据库只需对Checkpoint后的重做日志进行恢复。这样就大大缩短了恢复的时间。
缓冲池不够处理
  • 当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,若此页为脏页,那么需要强制执行Checkpoint,将脏页也就是页的新版本刷回磁盘。
重做日志不可用
  • 重做日志出现不可用的情况是因为当前事务数据库系统对重做日志的设计都是循环使用的,并不是让其无限增大的,这从成本及管理上都是比较困难的。重做日志可以被重用的部分是指这些重做日志已经不再需要,即当数据库发生宕机时,数据库恢复操作不需要这部分的重做日志,因此这部分就可以被覆盖重用。若此时重做日志还需要使用,那么必须强制产生Checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置。

InnoDB存储引擎实现

Log Sequence Number
  • 其是通过LSN(Log Sequence Number)来标记版本的。而LSN是8字节的数字,其单位是字节。每个页有LSN,重做日志中也有LSN,Checkpoint也有LSN。可以通过命令SHOW ENGINE INNODB STATUS来观察:
SHOW ENGINE INNODB STATUS;

Log sequence number 11154771130
Log flushed up to   11154771130
Pages flushed up to 11154771130
Last checkpoint at  11154771130

Checkpoint分类

  • Checkpoint发生的时间、条件及脏页的选择等都非常复杂。而Checkpoint所做的事情无外乎是将缓冲池中的脏页刷回到磁盘,不同之处在于每次刷新多少页到磁盘,每次从哪里取脏页,以及什么时间触发Checkpoint。在InnoDB存储引擎内部,有两种Checkpoint,分别为:Sharp Checkpoint 和Fuzzy Checkpoint。
Sharp Checkpoint
  • 发生在数据库关闭时将所有的脏页都刷新回磁盘,这是默认的工作方式,即参数innodb_fast_shutdown=1。
    但是若数据库在运行时也使用Sharp Checkpoint,那么数据库的可用性就会受到很大的影响。故在InnoDB存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只刷新一部分脏页,而不是刷新所有的脏页回磁盘。
Fuzzy Checkpoint
  • 在InnoDB存储引擎中可能发生如下几种情况的Fuzzy Checkpoint:
  • Master Thread Checkpoint;
  • FLUSH_LRU_LISTCheckpoint;
  • Async/Sync Flush Checkpoint;
  • Dirty Page too much Checkpoint;
Master Thread Checkpoint
  • Master Thread 中发生的Checkpoint,差不多以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘。这个过程是异步的,即此时InnoDB存储引擎可以进行其他的操作,用户查询线程不会阻塞。
FLUSH_LRU_LIST Checkpoint
  • 是因为InnoDB存储引擎需要保证LRU列表中需要有差不多100个空闲页可供使用。在InnoDB1.1.x版本之前,需要检查LRU列表中是否有足够的可用空间操作发生在用户查询线程中,显然这会阻塞用户的查询操作。倘若没有100个可用空闲页,那么InnoDB存储引擎会将LRU列表尾端的页移除。如果这些页中有脏页,那么需要进行Checkpoint,而这些页是来自LRU列表的,因此称为FLUSH_LRU_LIST Checkpoint。
Async/Sync Flush Checkpoint

Async/Sync Flush Checkpoint指的是重做日志文件不可用的情况,这时需要强制将一些页刷新回磁盘,而此时脏页是从脏页列表中选取的。若将已经写入到重做日志的LSN记为redo_lsn,将已经刷新回磁盘最新页的LSN记为checkpoint_lsn。

Dirty Page too much
  • 即脏页的数量太多,导致InnoDB存储引擎强制进行Checkpoint。其目的总的来说还是为了保证缓冲池中有足够可用的页。其可由参数innodb_max_dirty_pages_pct控制:
SHOW VARIABLES LIKE 'innodb_max_dirty_pages_pct';
Variable_name: innodb_max_dirty_pages_pct Value: 75

innodb_max_dirty_pages_pct值为75表示,当缓冲池中脏页的数量占据75%时,强制进行Checkpoint,刷新一部分的脏页到磁盘。在InnoDB 1.0.x版本之前,该参数默认值为90,之后的版本都为75。

Checkpoint机制

  • 在Innodb事务日志中,采用了Fuzzy Checkpoint,Innodb每次取最老的modified page(last checkpoint)对应的LSN,再将此脏页的LSN作为Checkpoint点记录到日志文件,意思就是“此LSN之前的LSN对应的日志和数据都已经flush到redo log

  • 当mysql crash的时候,Innodb扫描redo log,从last checkpoint开始apply redo log到buffer pool,直到last checkpoint对应的LSN等于Log flushed up to对应的LSN,则恢复完成:

如上图所示,Innodb的一条事务日志共经历4个阶段:

创建阶段:事务创建一条日志;

日志刷盘:日志写入到磁盘上的日志文件;

数据刷盘:日志对应的脏页数据写入到磁盘上的数据文件;

写CKP:日志被当作Checkpoint写入日志文件;

对应这4个阶段,系统记录了4个日志相关的信息,用于其它各种处理使用:

Log sequence number(LSN1):当前系统LSN最大值,新的事务日志LSN将在此基础上生成(LSN1+新日志的大小);

Log flushed up to(LSN2):当前已经写入日志文件的LSN;

Oldest modified data log(LSN3):当前最旧的脏页数据对应的LSN,写Checkpoint的时候直接将此LSN写入到日志文件;

Last checkpoint at(LSN4):当前已经写入Checkpoint的LSN;

对于系统来说,以上4个LSN是递减的,即: LSN1>=LSN2>=LSN3>=LSN4.

SHOW ENGINE INNODB STATUS;

Log sequence number 11154771130
Log flushed up to   11154771130
Pages flushed up to 11154771130
Last checkpoint at  11154771130
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值