![0ca25de8debd616c37b723a3206455db.png](https://img-blog.csdnimg.cn/img_convert/0ca25de8debd616c37b723a3206455db.png)
1. 开篇
MySQL 在查询数据时,对于 InnoDB 存储引擎而言,会先将磁盘上的数据以页为单位,先将数据页加载进内存,然后以缓存页的形式存放在「Buffer Pool」中。Buffer Pool 是 InnoDB 的一块内存缓冲区,在 MySQL 启动时,会按照配置的缓存页的大小,将 Buffer Pool 缓存区初始化为许多个缓存页,默认情况下,缓存页大小为 16KB。
为了方便理解,对于磁盘上的数据所在的页,叫做数据页,当加载进 Buffer Pool 中后,叫做缓存页,这两者是一一对应的
在 MySQL 启动初期,Buffer Pool 中的这些缓存页都是处于空闲状态,也就是还没有被使用,而随着 MySQL 的运行时间越来越长,这些缓存页渐渐地都被使用了,用来存放从磁盘上加载的数据页,导致空闲的缓存页就越来越少。当某一时刻,所有空闲的缓存页都被使用了,那么这个时候,从磁盘加载到内存中的数据页该怎么办呢?
![d1e8ad0849d3546352c6001805d36410.png](https://img-blog.csdnimg.cn/img_convert/d1e8ad0849d3546352c6001805d36410.png)
2. LRU算法
既然没有空闲缓存页了,而又想使用缓存页,那么最简单的办法就是淘汰一个缓存页。应该淘汰谁呢?当然是淘汰那个最近一段时间最少被访问过的缓存页了,这种思想就是典型的 LRU 算法了。
LRU 是 Least Recently Used 的简写,这个算法的实现就是淘汰最久未使用的数据,它通过维护一个链表,每当访问了某个数据时,就将这个数据加入到链表的头部,如果数据本身存在于链表中,那么就将数据从链表的中间移动到链表的头部,这样最终下来,在链表尾部的数据一定就是最久未被使用的数据了,因此可以将其淘汰。
将 LRU 算法应用到缓存页的淘汰策略上,那么就是在 InnoDB 存储引擎层内部,维护了一个链表,这些链表中的元素存储的就是指向缓存页的指针。
在 MySQL 启动的时候,这个链表为空。MySQL 启动以后,在进行数据查询时,InnoDB 会先判断要查询的数据所在的数据页,是否存在于 Buffer Pool 的缓存页当中,如果不存在,就从磁盘中读取对应数据页,存放到 Buffer Pool 一个空闲的缓存页当中,然后将这个缓冲页放入到链表的