1. 如何配置
默认是128MB,参数innodb_buffer_pool_size进行调整。
[server]
innodb_buffer_pool_size=2147483648
2. Buffer Pool 存储的数据
数据页,磁盘上存放的数据页的大小是16KB。
Buffer Pool默认的缓存页的大小跟磁盘页的大小是一一对应的
每个缓存页,都会有一个描述信息,包含:这个数据页所属的表空间、数据页的编号、这个缓存页在Buffer Pool的地址以及别的杂七杂八的东西。
3. free链表
数据库有一个哈希表,用表空间+数据页号作为key,然后缓存页的地址作为value。
当要使用一个数据页时候,如果不在哈希表中,则从磁盘加载进来。
4. flush链表
脏页,即更新了Buffer Pool的页,跟磁盘上的数据页不一致的页。
flush链表就是记录哪些缓存页是脏页的。
5. 预读机制
(1)innodb_ahead_threshold,默认值是56,意思就是顺序的访问了一个区里的多个数据页,访问的数据页的数量超过这个阈值,就会触发预读机制,把下一个相邻区的所有数据页都加载进缓存
(2) 如果Buffer Pool里缓存了一个区里的13个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会直接触发预读机制,把这个区里的其他的数据页都加载。
innodb_random_read_ahead。默认是OFF,也就是关闭的。
6. 基于冷热数据分离设计的LRU链表
LRU链表拆分为两个部分,一部分是热数据,一部分是冷数据,有innodb_old_blocks_pct,默认是37,也就是冷数据占比37%
第一次加载放在冷数据的头部,在缓存1s后还有访问,则移动到热数据的头部。
innodb_old_blocks_time,默认值是1000,也就是1000ms。
预读进来跟全表查询进来的缓存页数据,如果没有访问还是停留在冷数据区域,淘汰的时候直接淘汰冷数据尾部。这个设计可以借鉴,用作以后自行设计热冷数据缓存上。
mysql热数据前面1/4的缓存页访问到,不移动到头部,后3/4访问才移动,频繁移动对性能有损失。
7. 缓存页刷入磁盘
- 定时刷入,后台运行一个定时任务,把冷数据尾部的一些缓存页输入磁盘,加回free链表;
- flush链表中的一些缓存页也是定时刷入磁盘,从flush链表和lru链表移除,加入free链表;
- 实在没有空闲的缓存页了,从LRU链表的冷数据区尾部找到一个缓存页,刷入磁盘。