2、Buffer Pool的缓存页以及相关链表
2021-10-16 16:34:57 2 举报
Buffer Pool是数据库中用于缓存数据页的内存区域。它包含多个缓存页,每个缓存页都存储着从磁盘读取的数据页的副本。这些缓存页按照一定的算法进行组织,以便快速地检索和替换数据页。 为了管理这些缓存页,Buffer Pool还维护了一些相关的链表。例如,LRU(最近最少使用)列表用于记录最近被访问过的缓存页,以便在需要时可以快速地找到它们。此外,脏页链表用于记录已经被修改但尚未写入磁盘的数据页,以便在合适的时机将它们刷新到磁盘上。
作者其他创作
大纲/内容
数据页(16KB)一行数据一行数据一行数据
free链表是一个双向链表数据结构每个节点是一个空闲的缓存页的描述数据块
flush刷回磁盘
进入冷数据区域:1.预读1S后未访问的2.全表查询等带来的,1S后未访问
发生数据修改后会同时加入到flush链表中
描述数据
free_next = null
加入一个结点后
行
缓存页
结束结点
缓存页(16KB)一行数据一行数据一行数据
LRU链表判断哪些缓存页可清除
基础结点(40字节)count = n
block_id = block01
原因
1.冷数据的占比innodb_old_blocks_pct,默认值37,也就是冷数据占比37%2.刚进入冷数据区域的数据多久之后访问才移动到热数据表头:innodb_old_blocks_time,默认值1000,也就是1000毫秒
free、flush、lru双向链表都只占用一个基础结点的空间
数据页
先刷入磁盘再释放
缓存页(热数据区域)
free_pre = nullfree_next = null
2.取这行数据所在的数据页到缓冲池中(加载数据页到Buffer Pool中)
表空间
定时将冷数据区域末尾刷到磁盘
冷数据区域
在MySQL不繁忙的时候,将flush链表中的缓存页都刷入磁盘中这些缓存页的描述数据也会从flush链表和lru链表中移除,然后加入到free链表中去
表
数据库的核心数据模型:表+字段+行
3、根据描述数据找到对应空的缓存页
5、将描述信息写入到描述数据中
基础结点
//刚开始的第一个节点
数据库启动
直接释放掉内存
IO线程
4、将数据页数据写入到缓存页中
极端情况下,每次CRUD,都先要刷一个缓存页到磁盘,然后再从磁盘读取一个数据页到缓存页中要进行两次磁盘IO
怎么知道哪些缓存页是空闲的?如何将数据页读取到缓存页中?如何知道数据页有没有被缓存?
1.表空间号:sql的database+tabel解析出来2.数据页号:一致性算法算出来
热数据区域只有后3/4数据被访问才会移动到表头
chunk
刚加入到LRU中时,先放在冷数据区域的表头
MySQL预读机制
buffer pool总大小=(chunk大小 * buffer pool数量)的2倍数
分配扩容
lru尾部定时刷回磁盘
block03缓存页
flush双向链表
6、回写缓存到哈希表中
free链表不够,需要释放1.按理应该释放block022.但是预读机制将其挡在LRU链表前列3.实际上释放的是block03这是不合理的
block_id = block02free_pre = block01free_next = block03
优化策略
在2位置移除3
磁盘
同时将该描述数据加入free链表
buffer pool在运行期间是不能动态的调整自己的大小
free双向链表
基于冷热数据分离的方案来优化LRU算法
buffer pool三种随机刷盘
描述数据包含:该数据页所属的表空间、数据页编号、在Buffer Pool中的地址等信息
动态调整buffer pool大小,比如buffer pool本来是8G,运行期间你给调整为16G若这个时候向操作系统申请一块新的16GB的连续内存,然后把现在的buffer pool中的所有缓存页、描述数据块、各种链表,都拷贝到新的16GB的内存中去。这个过程是极为耗时的,性能很低下,是不可以接受的
从磁盘上加载一个数据页的时候,可能会连带着把这个数据页相邻的其他数据页,也加载到缓存里去
flush链表判断哪些缓存页是脏页
1.操作一行数据
LRU双向链表
开始结点
从free链表脱离后直接进入LRU链表
1、先从数据页缓存中寻找数据页
冷热区内存不够刷盘
1.冷数据区域不够时:新数据过来,淘汰尾部2.热数据区域不够时冷数据1S后被访问,热数据移动到冷表头
block02缓存页(顺带,预读)
按照配置在OS中申请一块内存
否
清除缓存页找尾部结点删除
block_id = block02free_pre = block01
描述数据块从free链表里移除
block01缓存页(新)
描述数据大小相当于缓存页的5%左右16KB * 5% = 0.8KB
2、若数据页哈希表中未找到数据则从free链表中获取描述数据
是否在flush链表中
定时任务
//因为缓存页有数据//肯定不在free链表中
基础结点start = block01end = block02count = 2
从磁盘加载数据页到缓存页的时候,就会把这个缓存页的描述数据块放到LRU链表冷数据区头部
缓冲池 Buffer Pool128M
一个缓存页对应一个描述信息
flush链表通过缓存页的描述数据块中的两个指针,让被修改过的缓存页的描述数据块,组成一个双向链表
目标数据页相邻的也加载进来了
1S后再次被访问才会调到热数据区域的表头
缓冲池默认:128Minnodb_buffer_pool_size建议设置到内存的50%-60%(不包含描述数据)
判断哪些数据页是被缓存的
free链表查看哪些缓存页是空的
是
数据页哈希表key:表空间号 + 数据页号value:缓存页地址
free_pre = nullfree_next = block02
热数据区域
MySQL InnoDB存储引擎
0 条评论
下一页