1. 基于冷热数据分离的思想设计LRU链表
MySQL在设计LRU链表的时候,采取的实际上是冷热数据分离的思想。
前面的问题,都是由于所有缓存页都混在一个LRU链表里,才导致的。
真正的LRU链表,会被拆分为两个部分,一部分是热数据,一部分是冷数据,这个冷数据的比例是由 innodb_old_blocks_pct 参数控制的,它默认是37,也就是说冷数据占比 37%。
LRU链表实际上看起来是下面这样子的。
2. 数据页第一次被加载到缓存的时候
在知道LRU链表是按照一定的比例被拆分为了冷热两块区域后,接下来看看在运行期间,冷热两个区域是如何使用的。
首先数据页第一次被加载到缓存的时候,这个时候缓存页会被放在冷数据区域的链表头部,也就是说第一次把一个数据页加载到缓存页之后,这个缓存页实际上是被放在下图箭头的位置,也就是冷热数据区域的链表头部位置。
3. 冷数据区域的缓存页被放入到热数据区域的时机
第一次被加载了数据的缓存页,都会不停的移动到冷数据区域的链表头部,而把冷数据区域的缓存页移动到热数据区域是由规则去决定的。
MySQL中设定了一个规则,它设计了一个 innodb_old_blocks_time 参数,默认值1000,也就是1000毫秒。
也就是说,必须是一个数据页被加载到缓存页之后,在1s之后,你访问这个缓存页,它才会被挪动到热数据区域的链表头部去。
这里要注意的是,如果是数据刚加载到缓存页,在1s内你就访问缓存页,此时他是不会把这个缓存页放入热数据区域的头部的。
4. 总结
数据页第一次被加载到缓存页之后,这个缓存页是放在LRU链表的冷数据区域的头部的,然后必须是 1s 过后访问换个缓存页,它才会被移动到热数据区域达到链表头部。