00:00
好同学们,咱们刚才的话呢,就关于咱们说的这个lo呀,啊,其实提到了两个结构啊,一个呢叫lo buffer,一个呢叫lo是吧?哎,那么什么时候从这个buff呢盘到这个呢,咱们就提到这个叫盘的这个策略了,包括呢,从代码层面呢,咱们也演示了这个不同的这个策略啊,它对应的这个效情况如何,包括呢,这个安全性如何,怎么去保证这个持久性,哪个呢会更好一些是吧,这个我们都说清楚了,那么接下来的话呢,咱们就有一个整体到部分啊,刚才呢是整体下边呢,我们就进入这个部分的环节,就专门来讲一讲这个redo buffer啊,以及呢我们这个redo file啊,这个呢,就是整个我设计这个个课程的一个思路啊。呃,应该是比较清楚的哈,这个应该说啊,我整理这一章呢,也确实花了很多的时间,当然你别看呢,咱们这一章呢,似乎好像这个章节不是很大,呃,就这个一万多个词儿是吧,但其实呢,诶为了把这一章呢能够弄清楚啊,捋顺清楚,方便大家呢很快的能够掌握啊,其实我看的这个相应的这个文字啊,诶至少不低于这个十几万了,然后呢,从这些文文字当中呢,然后整体呢去整整理,然后呢梳理出一条这个脉络来啊,确实呢,花的精力要多一些啊,那么这里边呢,需要去把握一个点,就是呢,呃,既不能不讲,讲的太泛泛是吧,讲的太泛泛的话呢,那大家理解的就不够深刻,那也不能呢讲的太这个靠里了,什么叫太靠里呢?就是我们讲的这个redolo buffer,比如说里边关于具体的这样的一个,呃,Redo lock block,它不是又分成这个叫呃日志头,日间日日体和日间日志尾嘛,这里边的话又分成几个字节是这个,几个字节是这个啊那这呢,哎,我也写了哈,但是这里边这个细节它的作用再去演示诶就没有必要了。
01:39
咱们就没有必要的,像讲这个数据页的时候呢,呃,提到这个行格式啊,提到这个数据页的内部结构啊,咱们讲的那么细致了啊,就是相当于呢,这个点的话呢,始终往里挖,它肯定会有东西,那我们也要相应的适可而止,对吧?诶大家呢,毕竟这个精力也是有限的啊,关于数据库我们掌握到啊,我现在呢,给大家这个内容的层面呢,应该说已经是足可以了啊,你足可以去卷别人偷偷的啊,一点问题没有啊。
02:04
所以大家呢,可以这个来来一波这个666是吧,给这个刷一波啊好,那么下边的话呢,咱们就进入这样的两个过程啊,叫做这个呃,写入redo lock buffer的一个过程,以及呢,我们关于redolo file啊这样一个讲解啊,那如果说呢,大家呢,呃,只是呢,想通过我们学习MYQL这个高级的课程啊,进行一些调优啊,那么这个层面的话呢,其实你学习到刚才这个就可以了,因为我们也讲的刚才提到的这个参数的一个设置了,这对于我们调优呢是有帮助的,对吧?那么接下来这个过程呢,其实对于调优来讲呢,其实就意义不大了,只能说呢,我们是再进一层啊,去了解一下我们这两个结构的一个底层的一个设计情况。啊,一个设计情况好,呃,那做一个了解就可以了啊呃,但是整个花的时间应该也不会太长,所以大家呢,也可以听一听啊,我觉得对你啊,以后参与相关的一些比如说框架呀,啊,关于这个数据库的二次开发呀,我觉得也是很有借鉴意义的啊,那我们来看一下。啊,首先呢,我们来看一下这个lock buffer啊,它的一个写入过程啊,要想说清楚这个事儿啊,哎,我们需要给大家引入一个概念叫做mini transaction。
03:07
啊说MY对这个把对底层页面中的一次原子访问的过程呢,就称为是一个叫。啊,一个呃,原子访问的过程叫mini传塞,简称呢叫MT2了啊那么呃,一个所谓的MT2呢,可以包含一组蕊度日志啊这个大家你看能不能理解啊,啊你比如说呢,我们现在就想像这个呃表中啊,咱们说某个索引对应的这个B加数中,我想插入一个记录,那么这呢就相当于是一次原子操作啊我们呢,就把它称为是一个MTR,说这一个MTR当中,它可能会包含一组维度日志,为什么这么讲呢?你比如说我们像这个B加数当中,咱们想一个树叶中插入一条记录了啊,放在这条记录和这条记录中间,那其实你会意味着是不是这条记录呢要往后移,那有可能我们这个页呢都满了,你是不是还得涉及到这个页呢?得往下一页去移了,对吧,诶这个移到哪,然后中间这块呢,我们就空出来,诶这里边呢,其实它是有多个这个蕊度日志的,咱们说了蕊度日志记录的是那个物理磁盘上的那个,你具体的操作是吧,哪个页当中呢,哪个位置偏移量是多少,做什么样的移动和修改。
04:14
所以呢,它一定是有多个这个维度的一个日志的记录的啊,这个没问题是吧。啊,那么再者说的话呢,我们说一个事物呢,可能包含多个语句啊,那每一个语句呢,它是由若干个MTR构成的,那整体来讲呢,就是这样一个关系,这个大家能不能理解。啊,你比如说咱们呢,写了一个update啊,Update这样一个表,然后修改,比如说工资是5000的改成6000,你这一个语句当中,你是不是要改我们底层多个这个位置啊,啊,因为呢,呃,Salary是5000呢,可能有多个位置都需要改,每个位置呢,相当于就是一个原子化的一个访问,是不是就是一个MT2啊,然后这一个MT2呢,有可能刚才我们提到了,是不是有可能又对应了多个这个度的一个日志记录。诶,所以这块呢,诶大家明确这样一个关系写啊,诶这个关系清楚了,我们才能够说这个redolo buffer这样的一个写入过程。
05:04
没问题是吧,好,那么下面的话呢,我们看具体一个过程。咱们在上边呢,整体讲解的时候呢,说过啊说过这个redo log buffer呢,它呃在内存中呢,是这样的一片区域啊,那么这个区域当中呢,是不是有一个一个的叫redo lock redo block叫block来构成的啊,这一个呢,就是一个block block了,就是一个块的意思了。对吧,诶这个块,这个块多大呢?诶我们说了是512的个字节啊,512个字节啊就这样子的,那么这个block呢,它又由三部分构成,一个呢叫block block,呃,Block block header叫这个日志头,这呢叫日志题,这个呢叫志尾啊这样的三部分啊头尾咱们其实是不存数据的,主要的数据呢,就放在咱们这个保底当中。哎,包D当中,那因为这个包D里边其实放的是不是就是一个一个的锐度,杠一杠二,诶杠N是吧,好,那么我们要把刚才提到的你这个锐度的这个日志啊,是不是咱就诶往内存中的这块去放,诶你往这里边去填就行啊填满了就意思往后走走走走走诶就走到这了,相当于我们目前呢,诶内存当中呢,咱们就用到这儿了,然后你要是再有这个锐度日志去记录的话呢,是不是就接着往下挤,记到这满了,是不是接着就往这挤。
06:15
诶,就是这样的一个过程啊,先明确一下好,那么你现在到哪了,是不是得通过一个变量去记录一下啊,这个变量呢,叫做buff利。哎,就是这样一个变量啊,它记录一下我们当前呢,是使用到哪了啊,这个呢比较好理解没问题是吧?好接接着我们往下说啊。说呢,一个MT2呢,它的执行过程当中呢,会产生若干条度日质,咱们已经说过了,这一个MT2呢,它是满足这种原子性的啊,它不能分割了,那就意味着我们这些,呃,一个MTR中的这些日志啊,它就不能够分割,那就意味着我们要是往这里边儿放的时候呢,呃,一个MTR里边这些日志呢,必须要挨着。啊,那一个MT2呢,里边的二点,那不同的MT2呢,哎,这块我们给大家说啊,假设我们一个事物啊,我就不说一个事物里边有几个语句构成了啊,咱就不说有几个语句了啊假设呢,你有这个N个语句,然后N个语句呢,每个里边有N个,那就N方个,咱们就直接呢跨掉语句,直接看这MP2啊我们就假设呢,诶,这个事物一啊,它有两个MT2构成啊,我就称作成MT2杠,T1这个事物的第一个和MT2还是T1这个事物的第二个,这就有两个0MT2,然后事物二的话呢,也同样的道理。
07:24
对吧,诶,那我们说了一个MT2呢,是不是由多个这个瑞do人构成的,呃,这个呢,必须是个整体,他们要是往这里边存的这一块必须挨着,但是呢,这一块和这一块呢,是可以不挨着的。啊,是可以不挨着的啊,本身的话呢,我们说这个事物的话呢,是不是就是并发,可能是并发执行的,对吧?哎,那既然可能是并发执行的呢,那我们这两个事物呢,它就可能交替的存储在我们这个re log buffer当中。啊,那怎么存呢?诶我们说呢,现在呢,假设已经到这儿了,现在话呢,你啊咱们说就同时吧,啊加引号的同时是吧,执行我们一个T11个T2啊那这由于呢,我们各自呢,是不是有两个MT2,那有可能我们就是先把诶事务一里边的MT21呢,诶先写入到这儿了,那因为人家呢说了这个整体里边这个事,呃日志呢,必须挨着是吧,然后紧接的话呢,就不是你这个事物了,就是另外一个事物当中的呃一个MTR了,然后然后呢,呃又是其他的这个呢,因为我们就俩事物来演示了,啊假设这块我们就又回到提15的第二个MTR了,这一个呢,盛不下了,盛不下呢就再起个七个,还盛不下,那就接着再往后,哎,那你是用多少就算多少啊,就记录到这儿了。
08:31
啊,接入到这儿以后呢,接着就是你下一个MT2啊,是我们这个事物二的这个MT2的第二个,那就往这放就行啊相当于我们目前呢,这两个事物这不一共呢,是这个四个MT2,这四个MT2的话呢,你就这样的往这意思一个一个摆就行。啊,MTR内部的这些record必须得是完全挨着的啊,我们想强调的其实就是这个问题。清楚了吧?啊好的啊,那么下边的话呢,咱们还是由这个整体到部分,咱们不是说了这个整体的下面这个部分的话呢,就是对应的这一个block,这一个block呢,刚才提到了由日志头日日体和日志尾是吧,就这三部呢构成的,然后他们占据的这个大小呢,头呢是占12个字节,这个呢占八个字节,然后512呢,减去12减去八是不是就492个字节言IG我们中间呢,能存储这个啊record啊这个日志记录的这个呢,就是492字节,那为什么设置成512呢?啊这个呢就提到了,呃,这个算一个常识了啊,跟我们这个磁盘的扇区呢是有关系的介磁盘的扇区默认呢啊一个扇区呢,相当于是512个字节,那我们跟他呢,正好完全匹配。
09:36
哎,正好完全去匹配啊,那如果呢,你要写入这数据大于512字节,相当于你是不是要占据两个扇区啊,两个扇区的话呢,相当于就要转动磁盘呢,去找下个站区,首先呢需要花一些时间,那其次的话呢,呃,那如果说我们A扇区写入成功了,B扇区呢,写入失败了,可能由于磁盘扇区呢坏了等等这样一些问题,那我们可能会出现这种非原子性的操作,所以我们就完全给他匹配一下。啊,一个山区啊,相当于对应的就我们这一个block。
10:02
啊,这样的情况。好,那么具体的关于我们这个呃,这个叫呃日志头还是我们这个呃log尾这个里边呢,又包含了具体的一些字节,这些字段呢,它的意思是什么呢?我就不在这去解释了啊,有兴趣的同学呢,哎,我把这停留一下,你可以呢,稍微暂停一下,然后你看看这里边的意思是什么。啊,这个我们在讲的话呢,就有点过深了啊,包括里边呢,再去测试啊等等的,我们就不做这个事儿了,没必要适可而止,好,这个关于我们叫redolo buffer呢,咱们就说到这儿。然后接下来咱们看一下这个叫redolo。啊说这块有啥可说的,实际上里边呢,还是会有一些问题呢,可以去揪的啊,可以去揪的啊来我们一边讲的一边说。首先呢,在这里边我们涉及到一些这个参数啊,第一个啊叫D啊这个呢,就涉及到我们这个这个到底存在这个问题对吧?诶咱们呢,刚才呃也说过了,是不是默认情况下就在咱们当前这个数据目录下啊,是不是就是我们这样的两个文件吧。
11:03
啊,那为什么说在这儿呢,主要原因呢,是因为我们这样一个变量的记录的啊,我们可以呢去受一下。Are variables like。哎,这样诶啊这样粘过来,然后这么着一下。嗯,收啊,这个咱们受了,这个是不是应该在这个my soq里边去执行啊收。Variables like。诶这么着一下是吧,好这块呢,你会看到呢,它是一个叫点儿斜杠啊,它这相当于是一个根目录了,但是这个根目录呢,诶其实指的就是咱们当前这个数据目录啊,作为我们这个所谓的根目录,诶其实呢,就是我们刚才看到的这样一个路径啊,就这个路径啊,就相当于是放在这儿啊这个意思好,那么放在这里边呢,默认情况下呢,是有两个文件的,就我们刚才看到这两个文件啊,为什么这俩呢,其实就是由我们这个变量呢,来进行这个控制的啊,我在CTRLC下啊回到这儿我们再。哎,测试一下这个变量啊,收一下。
12:00
S Ali。哎,这么着,所以呢,你看到这个值呢,是二啊,那这个二呢,哎,对应的过来就是我们这里边儿的。嗯,诶在哪呢,第一个啊,第二个是吧,而且呢,再下一步呢,是不是就看到我们这个每一个文件这个大小了,这个文件大小的话呢,就是由我们下边诶这样的一个变量来进行控制的。哎,这个变量控制的这个我就不去演示了啊,直接说一下的话呢,就看到是这个值,这个值的话呢,刚才不就是这个值嘛,然后呢,一换算就是48兆,哎这样的大小行,那上面这个变量呢,咱们那会儿已经说过了啊,刷盘的这个策略啊,嗯,这边提到了,说我们这个叫呃,Log file size呢,最大值呢,可以是512个G,注意这个大小啊,咱们刚才说的默认有俩文件,是不是每个文件48兆,相当于呢,是整个目前咱们占用的空间呢,应该是48乘以二是不是96吧。96兆对吧,那咱们这儿呢,指的这个最大到最大这个值呢,是512G呢,不是说每个文件512G啊,是我们呢,诶group你有几个文件,然后每个文件呢,有个大小成一起的话呢,最大呢,不能超过512个G啊,其实这已经很大了,是吧,已经很大了。
13:11
行,这个呢,大家去了解一下,我们也可以呢,通过这种诶修改配置文件的方式呢,去设置我们这个文件每一个的大小。啊是这样一个情况啊,那如果说呢,我们这个数据库这个实例呢,更新的比较频繁啊,那这个时候呢,我们可以呢,去增大咱们这个group啊,以及呢,去呃这个设置一下我们每个这个文件的一个大小啊这里边儿呢,我们会看到这个整个文件的大小呢,就是这个48兆,其实并不意味着当前我们已经完全把这个文件呢都占满了啊,它其实会有一些是空的啊,那随着你这个事物的增加呢,它就相当于是会占用这个空间,那有同学会想说,诶那万一我们这个呃没有,就是提交以后这个事,这个这个事物这个还没有刷盘啊,这呢是我们说的这个内存是吧,这个呢是我们说这个磁盘啊,诶那如果说我们这个呃,把这个内存中的数据呢,咱们只要更新呢,是不是都要记录到这个redo这个log file当中了是吧。
14:01
啊,这个file当中了,好,那如果说呢,我们这个呃,内存中这个数据呢,假设呢,已经是更新到磁盘了,其实你这个lo file里边这个数据呢,按说呢,就没有必要再去存了,这是一部分对吧?但是呢,如果说我们这个内存到磁盘中这个呃刷盘这个操作呢,我们积累的太多了,超过了咱们现在提到的,诶你不是48兆嘛,乘以个二呢,是不是就是96兆,诶如果说我们这个呢,呃,带刷盘的这个数据呢,超过了96兆,相当于我们这个文件呢,是不是就乘不下了,那乘不下的时候呢,怎么办呢。啊,成不价的时候呢,当然是需要扩容了,但是的话我们讲哈,呃,这里边儿呢,会涉及到一个机制啊,涉及到机制就是说呢,我们这里呢,是可以存在这个重复利用的这个情况啊,你比如说呢,我们刚才提到了,呃,有一些数据呢,已经刷新到这个磁盘上了,我们还在这里边记录,是不是就没有必要了,诶我们把这个数据呢假设啊,我们现在假设待刷刷盘的数据呢,是90吧,诶咱们先做个算术题哈,待刷盘的这个数据呢,是90兆,那意味着90兆都要往这里放。
15:01
啊,或者呢,这个要考虑往这放了,现在我们里边呢,有假设呢,有十兆这个数据呢,其实是之前你记录的,现在呢,这十兆数据就已经是从内存刷盘到这个磁盘中了。啊,你要加一起的话呢,这100兆相当于是盛不下的,但是你要把这十兆呢,干掉以后,诶我们这96兆实际上是能够存下的,对吧?诶相当于呢,你就把之前呢,没有用的那个数据呢,给它覆盖一下就行了,那么这块呢,具体的是怎么来实现的呢?诶那这就是我们要讲的这个redo lock file里边的下边的这个机制了,诶这就提到叫日志文件组。好,刚才呢,我们提到了一个group呢,有俩文件,你也可以设置成多个,假设呢,我们这里边儿就有N个来说啊,一个两个啊等等等N其实是N加一个了,对吧?好,那么有这么多的这个日志文件,整个呢就构成了一个叫日志文件group,就这个组,然后呢,这个每个组的这个文件大小呢,都是一样大的,我们就通过这个参数呢来进行的设置啊没问题是吧。那么呢,我们说呢,这个数据呢,就呃从这个头部开始啊,去写入啊,写入写入写入写入写入,呃,那写到这个N的时候,写完了,写完以后怎么办呢?我们再翻回来,再从头这块去写啊,这是我们宏观上来讲的话呢,就是这样的一个过程。
16:10
诶,就这样一个过程啊,总共能写多少呢?啊,当然你最多要写的话呢,肯定是这样一个成绩了,那我们之所以能够从头来写,再去覆盖这个之前的数据,是因为在之前这个数据呢,我们定义呢,就是你已经诶就是从内存中已经刷盘到这个磁盘里了,前面的数据就不要了啊那么具体这个过程啊,算法是如何来设计的呢?诶大家来看啊,我们就涉及到两个诶变量。这两个编呢,叫做right position记录当前记录在位置啊,一边写一边后移,另外一个呢,叫做checkpoint啊,他呢来啊,它是当前要擦除的这个位置是吧?啊也是往后呢推移的啊这个呢,其实比较简单啊,我给大家说一下,我这呢把这个呃循环这个过程呢,就这样来画了啊1234啊0123,相当于我们是不是有四个这个呃日志的这个file啊,四个日志这个文件啊,那么在最初的时候呢,肯定这时候我们这所谓的两个变量呢,它就都在这个位置了。
17:04
啊,然后呢,呃,只要呢,我们往这个日志文件里边去写数据,咱们这个叫right position呢,就一直的呃往后这块去移啊一直往后移,相当于呢,最初的时候呢,这两个变量呢,都在这儿,然后呢,我们先移动的是不是叫right position,它就往这块移,移动去写是吧?假设呢,我们现在就写到这了,那你要接下来呢,再去往这个文件中写,是不是就接着在这个指针往后去移去写入就行,没问题吧,好,那么这个变量呢,它为什么往后移呢?呃,因为随着呃,你这个内存中的数据呢,是不是我们也会去刷新到这个磁盘中啊。刷新到这个磁盘中,只要你从内存中的数据刷新到这个磁盘中了,相应的我们在这个log file中去做记录就没有必要了,那那此时的话呢,相当于我们这个,呃,你已经是刷新到磁盘中的这个数据了,我们就从这个指针这个开始呢,它就往后去移,移动到呢就是诶到这儿,那意味着后边啊我们这个拆框这个这个指针跟这个指针中间的这个数据呢,相当于呢,就是目前呢,是在诶到这儿是吧,目前呢,在我们这个redo lock file中做记录了,但是呢,还没有刷新到磁盘中呢。
18:05
啊,那如果说你后边又刷新了,是不是这个指针就往后去赶啊,啊没问题,好,那么呢,大家你注意一下,我说呀,这个目前的这个right position这个位置到我们这个位置哈。这些数据啊,其实都是可以再去写入的,不只是到这儿了啊,因为呢,我们写到这儿呢,算是写满了,但是呢,你这些数据呢,是不是已经都刷新到磁盘了,我们也可以再去覆盖啊,诶那就意味着这个指针right position到我们这个check呢,这块呢,都是我们可以来进行协助的。好,那这块呢,就往这块去写写写写写写写好,这时候呢,我们这个right position呢,我已经到这儿了,跟这个check呢,他俩相当于是重复了。诶,其实言外之意呢,就是我们的red position呢,相当于是不是落了这个CHECK1圈啊啊,那么这个时候呢,如果下一刻check呢,接着往后移动了,那没问题啊,它俩移动中间的这个差距呢,仍然是你可以再次写入的一个,呃,空间的大小啊,那如果在下一刻呢,你是red position呢,要去超过这个了,这就麻烦了,因为我们呢,后边这个数据呢,还没有这个进行刷盘操作呢,你不能够去覆盖的啊,你要再想往后去写这个red position的话呢,那就意味着我们这个文件呢,真的是已经满了。
19:14
对吧,哎,真的已经满了,OK,行,那这呢,我们就把这个呃,Redolo file啊,它的这样的一个写入过程呢,咱们就给大家呢说清楚了啊,那整个呢,关于这个relo呢,咱们也就讲到这儿,诶当然呢,需要去整体把控的,就是我们提到一个叫writelo这样的一个策略啊,一定呢是先要把这个数据呢,写入到我们这个日志文件的,然后呢,你再考虑你内存中这个数据呢,去刷盘是吧,然后在这个图当中呢,诶我出现了一个结构叫做诶安度日志文件的一个位置。好,那么下面的话呢,咱们要讲解的那就是安度这个日志了。
我来说两句