【mysql】checkpoint技术

之前介绍了mysql原理的两个重要的概念:缓存和日志。

我们知道了缓存要被周期性的刷回磁盘,那么具体是怎么刷的呢?

首先对于redo日志来说,存在三个刷回的时机:

(1)主线程的周期,即每一秒一次;

(2)日志缓存已经使用了三分之一的空间;

(3)执行到commit了;

所以,我们看到了执行commit的时候,其实所做事情是很少的,因为都均摊到其他的线程了。我们只需要把redo的日志缓存刷回去即可,而且因为主线程会定期刷回一部分,commit的时候刷回的量很少,这样响应时间会很快。那么,commit的时候,我们难道不需要刷回数据缓存吗?万一宕机了,不是丢失了吗?

commit的时候确确实实是不会刷回数据缓存的,因为不需要,如果同时刷回数据,那么所需要的时间会大大增加,况且刷回数据的时候还涉及索引的修改等一系列问题,所以,commit的时候我们只刷回redo日志。也就是说刷数据和日志要比单刷日志慢得多,事务的完成是看日志刷成功没,所以在一定时间内,我们肯定希望刷回的日志越多越好,这样事务的commit的就会处理更多,吞吐量也更高。

总结一下数据和日志不一起刷回的原因:事务的完成是看日志刷回磁盘的(因为只要有日志,就可以重做事务,所以不需要刷回数据),那么我们肯定希望一定时间内刷回的日志越多越好,所以就让日志和数据分开刷回。

数据刷回是在checkpoint点进行的,每到一次checkpoint,都会强制把数据缓存刷回去,checkpoint的发生时机在innodb中非常复杂。那么为什么要定义checkpoint这个时间点呢?主要是为了减少下一次启动时,redo日志的查看量。假设没有checkpoint,那么宕机一次再开机,就需要把所有的redo日志过一次,重做commit的,撤销未commit的,工作量极大。

但是如果有了checkpoint,我们下一次开机的时候,数据库就只需要检查上一个checkpoint点之后的redo日志,因为之前的肯定已经被刷回磁盘了。

而且,每一次commit虽然只是刷回了日志而非数据,假设此时宕机了,那么数据没有被写入磁盘,下一次开机,就可以根据日志来重做redo(前提是commit已经写入日志),这样数据就不会丢失,数据库在开机前是必须做这项检查的。

因此数据和日志的刷回不是一起的,我们客户端提交的事务只会涉及日志的刷回,数据是由后台主线程checkpoint时间点做的,所以速度很快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值