怎么解决因全表扫描带来的 Buffer Pool 污染

全表扫描这种情况的查询,很多缓冲页其实只会被访问一次,但是它却只因为被访问了一次而进入到 young 区域,从而导致热点数据被替换了

LRU 链表中 young 区域就是热点数据,只要我们提高进入到 young 区域的门槛,就能有效地保证 young 区域里的热点数据不会被替换掉

MySQL 是这样做的,进入到 young 区域条件增加了一个停留在 old 区域的时间判断.

具体是这样做的,在对某个处在 old 区域的缓存页进行第一次访问时,就在它对应的控制块中记录下来这个访问时间:

如果后续的访问时间与第一次访问的时间在某个时间间隔内,那么该缓存页就不会被从 old 区域移动到 young 区域的头部

如果后续的访问时间与第一次访问的时间不在某个时间间隔内,那么该缓存页移动到 young 区域的头部

如果后续的访问时间与第一次访问的时间不在某个时间间隔内,那么该缓存页移动到 young 区域的头部,这个间隔时间是由 innodb_old_blocks_time 控制的,默认是 1000 ms

也就说,只有同时满足「被访问」与「在 old 区域停留时间超过 1 秒」两个条件,才会被插入到 young 区域头部,这样就解决了 Buffer Pool 污染的问题

 

只要我们提高进入到 young 区域的门槛,就能有效地保证 young 区域里的热点数据不会被替换掉这句话该怎么理解,为什么设置 innodb_old_blocks_time 这个参数为 1 秒,能有效的避免因为全表扫描带来的 Buffer Pool 污染呢?

一个数据页中含有多条记录,因此全表扫描的情况下一个数据页会被访问多次,数据页的第一次访问和最后一次被访问的时间间隔一般不会超过 1 秒,这样它就不会被移动到 young 区域,导致 young 区域中的热点数据淘汰掉,这样就能避免因为全表扫描导致的 Buffer Pool 污染了

posted @ 2024-03-25 20:24  变体精灵  阅读(27)  评论(0编辑  收藏  举报