基于冷热分离的LRU链表
MySQL中设计LRU链表,是将冷热数据分离,链表分为两部分,一部分是冷数据,一部分是热数据,冷热数据占比由配置项innodb_old_blocks_pct控制,默认为37,即37%是冷数据
在运行期间,数据页被加载到缓存页时,首先会被放在冷数据区域的链表头部
MySQL配置项innodb_old_blocks_time默认值1000(ms),即当你加载数据页到缓存页时,在1s后如果又访问了这个缓存页,那么它就会被移动到热数据链表的头部,因为此时MySQL认为你可能会经常访问该缓存页
基于冷热分离的LRU链表的设计思想很好的解决了MySQL预读机制带来的问题
MySQL预读机制会将数据页连带其附近的数据页都读入缓存页,导致LRU链表中原本被频繁访问的缓存页被移动到LRU链表的尾部并且被淘汰,这种设计是非常不合理的
但是基于冷热分离的LRU链表将LRU分为了两条链表,一条是热数据链表,存放那些经常被访问的缓存页,一条是冷数据链表,存放那些不被经常访问,有可能被淘汰的缓存页,所有的数据页读入到缓存页时首先会进入冷数据链表
热数据的移动
在热数据区域,如果一个缓存页被访问,不一定会立马移动到热数据链表的表头,因为频繁的移动链表也是有性能消耗的,因此,MySQL中设计为,如果热数据链表前25%的缓存页被访问,他们是不会被移动的,只有在后75%中的缓存页被访问,才会移动到表头,这样就能尽可能的减少链表中节点的移动,从而减小性能的损耗
什么时候将LRU链表中的冷热数据中的缓存页刷盘
定时刷盘,MySQL会起一个后台线程,运行定时任务,每隔一定的时间就将LRU链表的冷数据区域尾部的一些缓存页刷盘,然后清空这些缓存页,并放入free链表,从LRU链表删除,从Flush链表删除
什么时候把Flush链表中的缓存页刷盘
LRU刷盘只会将冷数据刷盘,但是热数据也是需要被刷盘的,因此MySQL后台线程也会在某个时间将flush链表中的缓存页都刷盘,然后这些缓存页被清空,从flush链表删除,从lru链表删除,放入free链表
空闲缓存页不足
如果Buffer Pool中的空闲缓存页不足,free链表都被使用了,lru链表中有一大堆的缓存页,flush链表中也有一堆缓存页,此时如果MySQL需要从磁盘文件中加载数据页到Buffer Pool,那么MySQL会从LRU链表的冷数据区域的尾部找到最不经常使用的缓存页,将其刷盘并清空,放入free链表,然后将数据页读入缓存页
MySQL通过冷热数据分离的LRU链表策略优化缓存管理,37%的链表用于冷数据,剩余部分为热数据。当数据页加载时,先进入冷数据区,若在1s内再次访问,则移动至热数据区头部。热数据链表中,只有后75%的页面被访问时才会移动到头部。定时刷盘和后台线程负责将冷数据刷盘并释放空间。当需要更多空闲缓存页时,会淘汰冷数据区尾部的页面。此设计减少了预读机制带来的不必要页面淘汰,提高了缓存效率。
1182

被折叠的 条评论
为什么被折叠?



