MySQL: 13 基于LRU算法淘汰Buffer Pool中的部分缓存

Posted 鮀城小帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL: 13 基于LRU算法淘汰Buffer Pool中的部分缓存相关的知识,希望对你有一定的参考价值。

1. Buffer Pool中的缓存页不够了怎么办?

在加载数据到缓存页的时候,必然是要加载到空闲的缓存里去的,所以必须要从free链表中找一个空闲的缓存页,然后把磁盘上的数据页加载到那个空闲的缓存页里去。

缓存页不够用了

随着不停的把磁盘上的数据页加载到空闲的缓存页里去,free链表中的空闲缓存页会越来越少,最终会发现free链表中已经没有空闲缓存页了。

此时面临的问题是,我还要加载数据页到一个空闲缓存页里该怎么办?

 2.如果要淘汰掉一些缓存数据,淘汰谁?

如果所有的缓存页都被写满了数据,此时无法从磁盘上加载新的数据页到缓存页里去,那么就只能淘汰掉一些缓存页了。

所谓淘汰缓存页,就是把一个缓存页里被修改过的数据,给刷回到磁盘上的数据页里去,然后这个缓存页就可以清空了,让他重新变成一个空闲的缓存页。

接着再把磁盘上你需要的新的数据页加载到这个腾出来的空闲缓存页中去。

 如果要把一个缓存页里的数据刷入磁盘,腾出来一个空闲缓存页,就需要知道应该把哪个缓存页的数据给刷入磁盘?

3.缓存命中率概念

所谓缓存命中率,假设现在有两个缓存页,一个缓存页的数据,经常会被修改和查询,比如在100次请求中,有30次都是在查询和修改这个缓存页里的数据,而不需要从磁盘加载数据。那么此时我们可以说这种情况下,缓存命中率很高。

另外一个缓存页里的数据,就是刚从磁盘加载到缓存页之后,被修改和查询过1次,之后100次请求组中没有一次是修改和查询这个缓存页的数据的,那么此时我们就说缓存命中率有点低,因为大部分请求可能还需要走磁盘查询数据,他们要操作的数据不在缓存中。

针对上述的两个缓存页,必然优先选择将第二个缓存页刷入磁盘中。因为第二缓存页中的数据很少更新,却还要空占一个缓存页,太浪费内存了。

4.引入LRU链表来判断哪些缓存页是不常用的

问题:怎么知道哪些缓存页经常被访问,哪些缓存页很少被访问?

解决以上的问题是,引入新的LRU链表,即Least Recently Used,最近最少使用的意思。

LRU链表的工作原理

假设从磁盘加载一个数据页到缓存页的时候,就把这个缓存页的描述数据块放到LRU链表头部去,那么只要有数据的缓存页,它都会放在LRU里,而且最近被加载数据的缓存页,都会被放到LRU链表的头部去。

假设某个缓存页的描述数据块本来在LRU链表的尾部,后续只要查询或者修改了这个缓存页的数据,也要把这个缓存页挪动到LRU链表的头部去,也就是说最近被访问过的缓存页,一定在LRU链表的头部。

 当你的缓存页没有一个空闲的时候,只要直接在LRU链表的尾部找到一个缓存页,那他一定是最近最少被访问的那个缓存页!

然后把LRU链表尾部的那个缓存页刷入磁盘中,再把需要的磁盘数据页加载到腾出来的空闲缓存页中就可以了。

脏页和非脏页的处理区别,脏页flush到磁盘,不是脏页的话,直接释放内存。

5.SQL中表、行与表空间、数据页的关系

在SQL语句里都使用到的是表和行的概念。而底层的Buffer Pool中用到的是表空间、数据页的概念。他们之间的关系如下:

简单来说,一个是逻辑概念,一个是物理概念。

表、列和行,都是逻辑概念,我们只知道数据库里有一个表,表里有几个字段,有多少行,但是这些表里的数据,在数据库的磁盘上如何存储我们是不关注的,所以这是逻辑上的概念。

表空间、数据页,则是物理上的概念,实际上在物理层面,你的表里的数据都放在一个表空间里,表空间是由一堆磁盘上的数据文件组成的,这些数据文件里都存放了你表里的数据,这些数据是由一个一个的数据页组织起来的,这些都是物理层面的概念,这就是他们之间的区别。

以上是关于MySQL: 13 基于LRU算法淘汰Buffer Pool中的部分缓存的主要内容,如果未能解决你的问题,请参考以下文章

innodb buffer pool小解

redis淘汰策略

MySQL: 16 基于冷热数据分离方案优化后的LRU链表如何实现缓存页的淘汰机制

算法LRU 最近最少使用算法

面试题LRU算法及编码实现LRU策略缓存

Redis 为何使用近似 LRU 算法淘汰数据,而不是真实 LRU?