MySQL所谓的脏页和“抖”一下是什么联系?

  在我们平时经常用到的sql更新语句,之前是认为只要sql执行,当前sql的操作会立马执行到服务器磁盘上并返回,但是后来我才知道,事实并非如此,在了解事实之前,首先可能需要先了解什么是redo log,什么是buffer pool,什么是changebuffer以及数据页。。

  首先,我们用一种比喻的手法,将MySQL比喻成一个古代的饭馆,很多客户都需要在“饭馆”进行消费,如果有客户来还账或者是赊账的话,一般掌柜的有两种操作:

  (1)第一种是,掌柜立马把掌管着整个饭馆所有流水账信息的厚厚的一大本账本拿出来,然后读取到对应的客人信息,在脑海里计算一下,然后将结果写入到账本内;

  (2)第二种做法,就是掌柜会先将客人要还钱或者要赊💰的信息记录到一个粉笔板上面,然后在空余时间,将粉板上面的记录一个个对到大账本中;

  这样看来,如果在mysql很空闲的时候,第一种做法是很高效的,但是mysql在大多数情况下都是很繁忙的,所以第一种法在现实生活中是相当低效的,很可能在查一个帐的期间外面就挤了一堆人在那等着还钱,所以,掌柜的一般会选择将记录快速的记录在粉板上面然后快速的应对下一个客人,之后在饭馆打烊或者空闲的时候将粉板上的记录一个个对到账本里。

  账本和粉板的配合过程,可以将随机IO写的耗时操作转为写日志的顺序写操作,这种做法也称为WAL,也就是先写日志再写磁盘。

  

 

   可以在图中看出,一个普通的update语句,首先会对要更新的数据行进行内存是否命中判断,如果在内存中就直接去更新内存的,否则的话就先到磁盘去查询到对应的数据行,然后读取到内存中(读数据到内存的过程需要耗点时间,因为是随机IO读),之后再对内存的数据行进行具体的更新操作,之后就开始写redolog操作,这里的操作,我个人最好的记忆方式是这样的:一个新的流水信息需要处理的时候,首先肯定是得先进掌柜的脑海里(也就是内存),因为数据实时保存在内存里是相当不安全的,而且也不可能记得很多,毕竟人的记忆空间(内存一般比较小)有限,所以既然不能直接去更新磁盘,那么就遵循WAL机制,将脑海里也就是内存里的数据先顺序刷到redolog中,这时就算掌柜的一下子忙忘了(服务器挂了,内存数据丢失了),也可以通过redolog的记录来进行内存重放,此时redolog进入prepare状态,接下来就是写入binlog,当binlog写入完成时,redolog就正式完成一个提交了!!

  ok,回到主题,为什么会出现抖的情况?

  (1)redolog是个文件,总有大小满的时候,每当填满时,都需要将redolog中的一部分数据刷到磁盘中,而这个过程,更新语句是无法执行的,也就是这个过程用户的请求被阻塞,至于为什么要阻塞呢?个人的理解建议是:在将内存更新完后记录进redolog这个过程,是一个密不可分的过程,因为在更新完内存时,如果服务器挂了内存数据丢失,并且redolog没有写进日志,那么内存中所有“脏页”(也就是未来需要更新到磁盘的页)都会丢失并且无法重放;

  (2)第二种,就是内存里的数据太多了,需要将一部分的脏页(更新缓存的数据行)flush到磁盘,这种操作也会对用户请求的操作造成性能影响,但是不会阻塞。。。

  总结就是:刷脏页这个操作会导致本来应该执行很快的操作sql,会“抖一下”!

posted @ 2019-10-14 01:34  Booker808  阅读(223)  评论(0编辑  收藏  举报