20.redo log刷盘时机


highlight: arduino-light

redo日志刷盘时机

redo log是什么时候写盘的?

redo log是在事务开始之后逐步写盘的。

之所以说重做日志是在事务开始之后逐步写入重做日志文件,而不一定是事务提交才写入重做日志缓存,原因就是:重做日志有一个缓存区Innodblogbuffer,Innodblogbuffer的默认大小为8M,Innodb存储引擎先将重做日志写入innodblogbuffer中。

innodblogbuffer_size 是 redo log buffer 的大小,如果 buffer 不够大,就会发生多次 IO write,将缓存中的数据刷到磁盘。

innodblogbuffer_size 越大,IO 次数越少。

第32问:innodblogbuffer_size 到底有什么作用? - 简书 (jianshu.com)

我们前边说mtr运行过程中产生的一组redo日志在mtr结束时会被写到log buffer中,可是这些日志总在内存里呆着也不是个办法,在一些情况下它们会被刷新到磁盘里。

redo log buffer刷盘

redo log在写的时候,都是一个事务里的一组redo log,先暂存在一个地方,完事儿了以后把一组redo log写入redo log buffer。

写入redo log buffer的时候,是写入里面提前划分好的一个一个的redo log block的,选择有空闲空间的redo log block去写入,然后redo log block写满之后,其实会在某个时机刷入到磁盘里去,如下图。

image.png

那么今天我们就来研究一下,到底redo log buffer里的redo log block什么时候可以刷入到磁盘文件里去呢?

另外,磁盘上到底有几个redo log日志文件?不可能大量的redo log日志都放一个文件里吧?磁盘空间会占用的越来越多吗?

首先,我们先来看看redo log block是哪些时候会刷入到磁盘文件里去:

☆log buffer空间不足时

Innodblogbuffer的大小是有限的(通过系统变量innodblogbuffersize指定),如果不停的往这个有限大小的Innodblog_buffer里塞入日志,很快它就会被填满。

如果当前写入Innodblogbuffer的redo日志量已经占满了log buffer总容量的大约一半左右,就需要把这些日志刷新到磁盘上。

☆事务提交时

我们前边说过之所以使用redo日志主要是因为它占用的空间少,还是顺序写,在事务提交时可以不把修改过的Buffer Pool页面刷新到磁盘,但是为了保证持久性,必须要把修改这些页面对应的redo日志刷新到磁盘。

一个事务提交的时候,必须把他的那些redo log所在的redo log block都刷入到磁盘文件里去,只有这样,当事务提交之后,他修改的数据绝对不会丢失,因为redo log里有重做日志,随时可以恢复事务做的修改

PS:当然,之前最早最早的时候,我们讲过,这个redo log哪怕事务提交的时候写入磁盘文件,也是先进入os cache的,进入os的文件缓冲区里,所以是否提交事务就强行把redo log刷入物理磁盘文件中,这个设置对应的刷盘策略。

☆后台线程不停的刷刷刷

后台有一个线程,大约每秒都会刷新一次log buffer中的redo日志到磁盘。后台线程定时刷新,有一个后台线程每隔1秒就会把redo log buffer里的redo log block刷到磁盘文件里去

正常关闭服务器时

MySQL关闭的时候,redo log block都会刷入到磁盘里去

忽略上面的第四种情况:正常关闭服务器时不说,因为关闭MySQL的时候必然会刷redo log到磁盘,其他三条其实我们都看到了。

第一种情况:log buffer空间不足时:如果你瞬间执行大量的高并发的SQL语句,1秒内就产生了超过8MB的redo log(总容量16MB),此时占据了redo log buffer一半的空间了,必然会直接把你的redo log刷入磁盘里去,如下图。

image.png

上面这种redo log刷盘的情况,在MySQL承载高并发请求的时候比较常见,比如每秒执行上万个增删改SQL语句,每个SQL产生的redo log假设有几百个字节,此时却是会在瞬间生成超过8MB的redo log日志,必然会触发立马刷新redo log到磁盘。

第二种情况:事务提交时:其实就是平时执行一个事务,这个事务一般都是在几十毫秒到几百毫秒执行完毕的,说实在的,一般正常性能情况下,MySQL单事务性能一般不会超过1秒,否则数据库操作就太慢了。

那么如果在几十毫秒,或者几百毫秒的时候,执行完毕了一个事务,此时必然会立马把这个事务的redo log都刷入磁盘,如下图。

image.png

第一种情况其实是不常见的。第二种情况是比较常见的,往往redo log刷盘都是以一个短事务提交时候发生的。

第三种情况就是后台线程每秒自动刷新redo log到磁盘去,这个就是说假设没有别的情况触发,后台线程自己都会不停的刷新redo log到磁盘。

但是不管怎么说,主要是保证一个事务执行的时候,redo log都进入redo log buffer,提交事务的时候,事务对应的redo log必须是刷入磁盘文件,接着才算是事务提交成功,否则事务提交就是失败,保证这一点,就能确保事务提交之后,数据不会丢,有redo log在磁盘里就行了

当然,绝对保证数据不丢,还得配置一个参数,提交事务把redo log刷入磁盘文件的os cache之后,还得强行从os cache刷入物理磁盘,这就是redolog的刷盘策略。

总结

不管脏页里的数据有没有同步到数据页。redo日志已经写完。

由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于定时任务。  

因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。另外引用《MySQL技术内幕 Innodb 存储引擎》(page37)上的原话:即使某个事务还没有提交,Innodb存储引擎仍然每秒会将重做日志缓存刷新到重做日志文件。这一点是必须要知道的,因为这可以很好地解释再大的事务的提交(commit)的时间也是很短暂的。因为redolog虽然刷盘,但是事务可以不提交!

问:会不会产生脏日志?

不会,因为日志如果被提交了会有提交标识。

参考:https://blog.csdn.net/zht245648124/article/details/129190852

参考:https://blog.csdn.net/zht245648124/article/details/129190871

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值