mysql 的innodb页的缓冲池概念buffer pool

详细:https://blog.csdn.net/liuming690452074/article/details/113811983

页,内存中,buffer pool  , 默认128M,每一个页默认的是16k,算下来就是有8192块。

Buffer Pool是数据库中我们第一个必须要搞清楚的核心组件,因为增删改操作首先就是针对这个内存中的Buffer Pool里的数据执行的,同时配合了后续的redo log、刷磁盘等机制和操作。

所以Buffer Pool就是数据库的一个内存组件,里面缓存了磁盘上的真实数据,然后我们的系统对数据库执行的增删改操作,其实主要就是对这个内存数据结构中的缓存数据执行的。

不管查询还是修改,会先将页,从磁盘中复制到bufferPool,  在内存中修改后,数据还是要回到磁盘的,这是内存空间可能又腾出来了。

这时,BufferPool的空间可能比较凌乱,有的被占,有的没有被占,当有新的页要放到bufferpool时,这时,就不知道将这新的页放哪里了?

-------------------------------------------------------------------------------------------------------------------------------------------

free链表,用来管理bufferPool的空白页,

其中基节点存:

1,哪个是第一个控制块

2,哪个是最后一个控制块

3,一共有有多少个控制块

控制块很小,存的是BufferPool对应页的指针,

当从磁盘取出一个页放BufferPool时, 先从free链表中找第一个控制块(头),把页数据放到控制块对应BufferPool指针的空间区域,同时把这个控制块从链表中(头)删除。

当BufferPool有页空间空出来时,就将这个页对应指针添加到fee链表中(尾), 在free链表中这样处理性能是很高的。 这样,就很方便的通过链表对BufferPool中的空白页进行管理。

修改数据:将要个修改的数据复制到BufferPool的页,此时修改的页我们叫它脏页

哪什么时将修改后的数据持久化磁盘呢?

mysql后台是有个进程,定时监控BufferPool哪些页是脏页(从flush链表中查找),然后把脏页持久化到磁盘中

这里又会有一个问题,哪些是脏页,怎么去判断呢

只要在BufferPool更新了页,就将这页地址添加到flush链表中,如果没有这个flush链表,就得在BufferPool中遍历了。

当BufferPool满了解怎么处理?

LRU(Least recently used),最近用的最少的淘汰掉!

同样的,也有一个链表,叫LRU链表,将最近的访问的,就放在第一个, 假如满了,就将LRU链表最后的淘汰。 

 但它有一个问题,就是如果突然来一个比较大的表 select * ,那么它就会把BufferPool热点页全淘汰,用新的页覆盖,这就是换血了,这时,就会因一次突然全表扫描,淘汰了热点的页,此时 MySQL性能急剧下降,这种情况叫缓冲池污染

怎么解决热数据不容易被覆盖呢?

LRU链表(升级版)其实分了热冷区域,  热占5/8,冷占3/8。 

来了一个新的查询,会将bufferPool页地址加到LRU链表冷数据区的头节点,再来一个,还是会加到冷数据区的头节点,这里就会有一个问题,一直在操作冷数据区,热数据区没有数据,

那么什么时候,将冷数据的控制块移到热数据区呢?

如果冷数据再次访问,加入冷数据区时间T1,第二次访问时间T2(全表扫描),T2-T1<1s,说明访问间隔很短,被认为是全表扫描,这时冷数据块不会移到热数据区,  如果T2-T1>1S(第一次这个页数据,第二次访问这个页超过1s,innodb才会理解为用户正常访问,如果小于1s,就会被当作全表扫描),就会将这个加到热数据第一个,成为热数据。

另一种解释:

怎么这类扫描大量数据导致的缓冲池污染问题呢?

MySQL缓冲池加入了一个“老生代停留时间窗口”的机制:

(1)假设T=老生代停留时间窗口;

(2)插入老生代头部的页,即使立刻被访问,并不会立刻放入新生代头部;

(3)只有满足“被访问”并且“在老生代停留时间”大于T,才会被放入新生代头部;

LRU

冷数据区域会占满? 占满就会清掉嘛。

上述原理,对应InnoDB里哪些参数?

有三个比较重要的参数。

参数:innodb_buffer_pool_size

介绍:配置缓冲池的大小,在内存允许的情况下,DBA往往会建议调大这个参数,越多数据和索引放到内存里,数据库的性能会越好。

参数:innodb_old_blocks_pct

介绍:老生代占整个LRU链长度的比例,默认是37,即整个LRU中新生代与老生代长度比例是63:37。

画外音:如果把这个参数设为100,就退化为普通LRU了。

参数:innodb_old_blocks_time

介绍:老生代停留时间窗口,单位是毫秒,默认是1000,即同时满足“被访问”与“在老生代停留时间超过1秒”两个条件,才会被插入到新生代头部。

猜你喜欢

转载自blog.csdn.net/liuming690452074/article/details/113810732
今日推荐