mysql checkpoint_MySQL checkpoint

MySQL innodb Checkpoint的设计和Oracle checkpoint类似,主要是为了缩短数据库恢复时间,buffer pool不够用时刷脏页到datafile,保证redo log file的循环使用而不会一直增大。

MySQL innodb引擎通过LSN(Log Sequence Number)来标记版本,通过show engine innodb status \G输出做解释:

---

LOG

---

Log sequence number 2722769

#LSN1,当前数据库系统LSN,最新事务的LSN

Log flushed up to   2722769

#LSN2,当前已写入redo log file的LSN

Pages flushed up to 2722769

#LSN3,当前最旧脏页数据对应的LSN

Last checkpoint at  2722760

#LSN4,当前已写入redo log file checkpoint的LSN

0 pending log flushes, 0 pending chkp writes

129 log i/o's done, 0.00 log i/o's/second

----------------------

LSN1>=LSN2>=LSN3>=LSN4

fc89322e9f0a2e3af120df8c112eb59f.png

检查点分为:

sharp checkpoint全量检查点 在数据库关闭时将脏页刷新到datafile ,通过参数innodb_fast_shutdown=1 或 0可以实现

Innodb_fast_shutdown告诉innodb在它关闭的时候该做什么工作。有三个值可以选择:

0表示在innodb关闭的时候,需要purge all, merge insert buffer,flush dirty pages。这是最慢的一种关闭方式,但是restart的时候也是最快的。

1表示在innodb关闭的时候,它不需要purge all,merge insert buffer,只需要flush dirty page。1是默认值。

2表示在innodb关闭的时候,它不需要purge all,merge insert buffer,也不进行flush dirty page,只将log buffer里面的日志flush到log files。因此等下进行恢复的时候它是最耗时的。

purge all,merge insert buffer的含义:

Purge all

这个操作主要是删除那些无用的undo页。对于delete操作,innodb是通过先将要删除的那一行标记为删除,而不是马上清除这一行,因为innodb实现了MVCC,这些undo段用来实现MVCC机制。MVCC也就是常说的多版本控制,锁不阻塞读,读也不阻塞写,这样大大提高了并发性。那么在一致性读的时候,怎么才能找到和事务开始的那个版本呢?对于主键索引,每个行都有一个事务ID和一个undo ID,这个undo ID指向了这行的先前版本的位置。对于非主键索引,也就是常说的secondary index,是通过先找主键索引再找到undo段。而对于update操作,则是先标记删除,然后insert一个新的行,接下来如果有一致性读,那么查找old version的行的原理和delete操作是一样的,详情见[1]。现在接着说purge all操作,随着DML的操作越来越多,那么回滚段必然也会越来越多导致占用了许多磁盘空间,那么innodb就会定期删除一些无用的undo页,首先,innodb重启的时候必然undo页都会无效所以会进行purge all操作,另外,随着时间的推移必然一些事务已经完成,它们已不再需要某些undo页,那么这些undo在mysqld running的时候也会定期的进行清除。

Merge insert buffer

Insert buffer是innodb的一个特性之一,在非聚簇、且不是唯一索引(即非主键索引、非唯一索引)的情况下,如果插入的索引行所属的页在buffer pool中就直接更新这个页,否则它会将这个索引行插入到insert buffer中,然后定期对这个insert buffer进行合并(合并的本质工作就是将insert buffer中的信息更新到真正的索引文件中去)。因为innodb的secondary index是非聚簇的,那么插入很有可能带来大量的随机I/O,而如果利用insert buffer对一些属于相同页的行进行合并,那么就会减少随机IO从而提高性能。但是这里需要注意的是,insert buffer和doublewrite buffer是类似的概念,他实际上属于system tablespace中的一部分[2],正由于它也是持久化存储,那么在服务器宕机或是重启之后这些信息不会丢失,所以也就有了在前面介绍innodb_fast_shutdown时所说:在innodb重启时,可能需要进行merge insert buffer。那么在什么情况下需要对insert buffer进行merge操作呢?

a>     在innodb restart的时候

b>     master thread会定期的进行merge操作

c>       每次读取secondary index page时,如果所需页不在buffer pool,而这些页在insert buffer中的时候,这时需要先对insert buffer进行合并,然后才能被读取。为什么这样呢?因为所有插入的索引行所属的页如果不在buffer pool中,而又在insert buffer中,那么它一定代表了页的最新状态(不理解?因为每次插入索引行的时候,如果所需页不在

buffer pool中就直接插入到insert buffer中,而一旦insert buffer merge后相关的行也就不在insert buffer更新secondary index page了)。这时或许你会问那么为什么不直接读取insert buffer中的页然后继续操作而一定要合并(更新到索引文件)呢?因为在innodb中是数据文件(也就是主键索引)和索引文件缓存的,在insert buffer中读取了需要的页后,那么必然就会在buffer pool中缓存了这个页,而如果这个页还留在insert buffer中却不更新到secondary index page去,那么,第一,这将不能保证索引文件得到更新;第二,insert buffer的空间会被占用。而如果这一步将insert buffer 合并后,不但减小了insert buffer的使用空间,而且将这merge操作完成了一部分,减小了以后merge的负担(不是有句话叫做今日事今日毕么),不过这也减慢了读的操作,因为读操作必须等待这个页的合并。

fuzzy checkpoint 部分页刷新检查点,主要4类:

1.master thread checkpoint

master thread周期性从cache pool的脏页列表种刷新一定比例的页到datafile,相关参数:innodb_io_capacity

2.FLUSH_LRU_LIST checkpoint

page cleaner thread通过innodb_lru_scan_depth数量刷新脏页

3.async/sync flush checkpoint

redo log file不可用时,强制将一些脏页刷新到datafile。sync位置时redo log的7/8处,async是redo log的3/4处

4.dirty page too much

buffer log脏页太多,达到innodb_max_dirty_pages_pct时强制进行checkpoint

参考:

MySQL DBA工作笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值