MYSQL : innodb引擎针对管理BP(Buffer_pool)的LRU算法

LRU算法核心就是淘汰最久未使用的数据,但是传统LRU算法有一些问题,即预读失效缓冲池污染。 MYSQL采用冷热数据分离的方式对传统LRU算法进行了升级来管理innodb_buffer_pool


1.什么是缓冲池污染

在批量读取数据或全表扫描的场景中或是访问冷数据时,大量的数据页被提前加载进来,但是并没有被高频访问,还导致了热点数据被后置到链表尾部甚至被冲出缓冲池。

1.1解决方案

冷热数据分离,形成新生代与老年代

  • 核心思想:
    当出现全表扫描时,按照传统LRU算法会直接给BP缓冲池从头到尾的全部换掉,一下子淘汰了已经稳定的热点数据。这样会导致BP的命中率直接被打乱,内存中无法查询,压力全部打到磁盘,最高频的SQL响应时间变得很慢。
  • 具体实现:
    innoDB升级的Buffer Pool LRU算法,用链表链接page页实现。LRU数据页链表,被5:3分为新生代young和老年代old,设计了冷热数据分离的处理方案。

    针对在批量读取数据或全表扫描的场景中,既用到了Buffer Pool还对young区域热点数据没有影响,从而保证了Buffer Pool的查询命中率。新page页载入后先放入老年代的头部,挤掉老年代的尾部,如果没有被继续访问就会比新生代还早淘汰,如果被访问到就放入新生代的头部,把新生代的尾部的数据页放入老年代的头部,这个过程不会有数据页被清除
  • Linux 操作系统对此的优化也是实现两个了 LRU 链表:活跃 LRU 链表(active_list)和非活跃 LRU 链表(inactive_list) 


2.什么是预读失效

进行批量读取时冷数据冲入(新生代),导致大量热点数据被换出,缓冲池污染,命中率下降,产生大量的磁盘 I/O

2.1解决方案

提升加入新生代的门槛,防止冷数据进入

  • 核心思想:
    缓冲池污染的问题在于,加入新生代的门槛太低,当数据预读后被访问不应该直接加入新生代,而是设立一些门槛防止冷数据换出热点数据,比如MYSQ设置了时间判断,如果同一内存页访问的时间间隔过小,那么直接在老年代解决这个污染数据
  • 具体实现:
    批量读取的预读数据(冷数据)放入老年代,如果这个page在LRU链表中第二次访问间隔时间大于1000毫秒,则进入新生代。否则就留在old区。解决这些大量数据只会被访问一次,把热点数据淘汰的问题,它们只会待在老年代中,后续很快也会被淘汰。
    这个间隔删除时间默认1000毫秒,由innodb_old_blocks_time参数决定。
  • Linux 操作系统:是在内存页被访问第二次的时候,直接将页从 inactive list 升级到 active list 里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值