19.redo log buffer

redo log buffer

我们执行完增删改之后,要写入磁盘的redo log,其实应该是先进入到内存redo log block这个数据结构里去的,然后再进入到磁盘文件里,如下图所示。

image.png

那么今天我们就来讲讲,这个redo log到底是如何通过内存缓冲之后,再进入磁盘文件里去的,这就涉及到了一个新的组件,redo log buffer,他就是MySQL专门设计了用来缓冲redo log写入的。这个redo log buffer其实就是MySQL在启动的时候,就跟操作系统申请的一块连续内存空间。

redo log buffer是申请出来的一片连续内存,然后里面划分出了N多个空的redo log block,如下图所示。

image.png

通过设置mysql的innodblogbuffer_size可以指定这个redo log buffer的大小,默认的值就是16MB,其实已经够大了,毕竟一个redo log block才512字节而已,每一条redo log其实也就几个字节到几十个字节罢了。

我们可以通过启动参数innodblogbuffer_size来指定log buffer的大小,我们生产是8G。

SHOW variables like 'innodb_log_buffer_size' ; 8388608/1024/1024=8GB

所以大家看到这里就明白了,上一讲我们就说了,其实redo log都是先写入内存里的redo log block数据结构里去的,然后完事儿了才会把redo log block写入到磁盘文件里去的。

这里我们看到了redo log buffer的结构,就很清晰的知道,当你要写一条redo log的时候,就会先从第一个redo log block开始写入,如下图。

image.png

写满了一个redo log block,就会继续写下一个redo log block,以此类推,直到所有的redo log block都写满。

那么此时肯定有人会问了,万一要是redo log buffer里所有的redo log block都写满了呢?

那此时必然会强制把redo log block刷入到磁盘中去的!

我们上一次讲到了redo log block刷入磁盘文件中的示意,其实就是把512字节的redo log block追加到redo log日志文件里去就可以了

看下面的图,里面就画的很清楚,在磁盘文件里不停的追加一个又一个的redo block。

image.png

另外还要给大家讲一点的是,其实在我们平时执行一个事务的过程中,每个事务会有多个增删改操作,那么就会有多个redo log,这多个redo log就是一组redo log,其实每次一组redo log都是先在别的地方暂存,然后都执行完了,再把一组redo log给写入到redo log buffer的block里去的。

如果一组redo log实在是太多了,那么就可能会存放在两个redo log block中,我们看下图示意。

image.png

但是反之,如果说一个redo log group比较小,那么也可能多个redo log group是在一个redo log block里的,如下图所示。

image-20230324182401163

image.png 想必今天的内容学习完,大家对于平时我们一个一个的事务里产生的多条redo log ,是如何形成一个redo log组的,一组redo log是如何写入redo log buffer中的redo log block的,然后redo block是如何写入redo log磁盘文件的,这个全流程就有了一个清晰地理解和认识了!

下周我们要继续探索的,就是这个redo log buffer里的redo log block们到底是如何写入到磁盘文件里去的?

一定要等待redo log block全部写满了才会刷入磁盘吗?还有哪些其他的时机会把redo log block刷入磁盘吗?

redo 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是哪些时候会刷入到磁盘文件里去:

(1) 如果写入redo log buffer的日志已经占据了redo log buffer总容量的一半了,也就是超过了8MB的redo log在缓冲里了,此时就会把他们刷入到磁盘文件里去

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

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

(3) 后台线程定时刷新,有一个后台线程每隔1秒就会把redo log buffer里的redo log block刷到磁盘文件里去

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

忽略上面的第四条不说,因为关闭MySQL的时候必然会刷redo log到磁盘,其他三条其实我们都看到了,也就是说,如果你瞬间执行大量的高并发的SQL语句,1秒内就产生了超过8MB的redo log,此时占据了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刷入物理磁盘。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值