mysql buffered_mysql-buffer pool

数据都是存储在磁盘中的,单查询某条记录的时候,mysql从表空间中取出对应的页,从磁盘加载到内存,当查询完不会立刻释放,而是缓存起来.

这个用于缓存的连续内存空间就是buffer pool,可以在配置文件中设置大小默认128m

buffer pool内部是由控制块和缓存页组成

控制块:保存着缓存页的属性控制信息

5e5a413fef141cc80b595c102a8bc98c.png

当我们需要存储磁盘页的时候需要知道存到哪个缓存页中,我们如何知道那个缓存页是空的呢?

free链表 mysql使用一个链表 来存储着空闲的缓存页,链表的基节点保存着链表的相关信息,mysql会创建一个hash表存储key 表空间号+页号 value为缓存也 方便使用缓存

flush链表修改过某个缓存页 对应的控制块都放入到这个链表中 方便某个时机写回磁盘 跟free链表一样有一个基节点

毕竟buffer pool的空间是有限的,作为一个缓存来说就面临着淘汰缓存,mysql的lru算法是什么呢?

这个面临着两个问题:

1. innodb有个预读的功能,线性预读如果顺序访问了某个区的页超过了innodb_read_ahead_threshold值, 将异步将这个区的页全部加载到buffer pool中 这个值默认56,

随机预读如果buffer pool中存储着一个区的13个页面,就把这个区的页异步加载到buffer pool中 加载的页被放到链表的前面,如果预加载的页不是被频繁用到,当需要淘汰的时候就被链表后面需要被频繁用到的删除了

2. 全表扫描把这个表所有的页加载到buffer pool ,频繁的执行全表操作,就会频繁将用不到的页加入buffer pool中,淘汰那些使用频繁的页了

为了解决这两点问题,mysql把lru链表分两个部分,一个存储使用频繁的页称为old页,一个存储使用频率没那么高的页称为young页

数据先被存入到old部分的头部,第一次访问处于old区域的页在对应的控制器加一个访问时间,后续访问计算访问间隔,若时间间隔超过系统设定的时间范围就把这个页移到young区域

这不是全部的lru策略,如果想了解更多请去看看源码哈~

mysql后台会每隔一段时间会flush脏页到磁盘

那么这个刷新策略是什么呢?

buf_flush_lru 定时从lru链表尾部刷新一些脏页到磁盘

buf_flush_list 定时从flush链表刷新一些脏页到磁盘

f60d09e50a41da8514b44c0f7812935c.png

为了处理多线程高并发,mysql把buffer pool分成多个实例,每隔实例由chunk组成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值