buffer pool是一种减少磁盘io读的机制,原理是将访问过的磁盘数据暂留在内存中,这样下次访问相同的数据就不需要读磁盘了。这个思想在平时的开发中,也经常用到,比如我们通常会在数据库前加一层memcache以及redis的缓存,防止热点数据。
mysql的内存缓存叫做buffer pool。缓存的单位是页,页是mysql管理磁盘的基本单位,也就是mysql每一次的磁盘io都是至少操作一个页的数据量。
buffer pool使用一种特定的lru算法管理缓存页。因为mysql读取磁盘有预读机制,简单来讲就是,读取一个页,也会读取相邻的若干页,因为根据经验,相邻页被使用的概率是比较高的。
由于有预读机制,导致使用传统的lru算法不合适。因为,预读的页可能没有被使用,所以不应该缓存。对于这些预读失败的页,mysql有特殊的处理机制。
简言之就是lru链表分为两部分:新生代及老生代。
新生代的尾部是老生代的开始。当一个页从磁盘被读入时,优先加入到老生代的链首,如果该页被访问到了,才将其移到新生代的链首,否则就一直在老生代中,所以,预读失败的页会优先被淘汰。
另外还有一个概念是"老生代停留时间窗口",新页进入到老生代后,只有停留时间超过一个阈值T后,才会被移到新生代,为了防止扫表导致的无效数据。(具体机制不确定。。。)
参数:
1.innodb_buffer_pool_size:buffer pool大小,貌似是尽可能大?;
2.innodb_old_blocks_pct:老生代比例;
3.innodb_old_blocks_time:老生代停留时间阈值;
参考:https://zhuanlan.zhihu.com/p/71698872
标签:buffer,mysql,pool,预读,MySQL,磁盘,老生 From: https://blog.51cto.com/u_15873544/5844584