关于MySQL缓冲池:Buffer Pool 与 Change Buffer

Buffer Pool🚩

作用:

  • 缓存索引页,数据页,提高查询性能
  • 更新记录,先缓存到buffer pool(Change Buffer),而不是直接写回磁盘,提高效率
Buffer Pool有多大

innodb_buffer_pool_size 参数用于设置 Buffer Pool 的大小,默认128MB

一般建议设置成可用物理内存的 60%~80%

Buffer Pool被划分成缓存页,默认一页16KB

InnoDB 为每一个缓存页都创建了一个控制块,控制块信息包括「缓存页的表空间、页号、缓存页地址、链表节点」等等

Change Buffer

Change Buffer写缓冲

Change Buffer默认占Buffer Pool的25%,最大设置占用50%:

Change Buffer是在【非唯一普通索引页】不在buffer pool中时,当对页进行了写操作时,在不影响数据一致性的前提下。InnoDB会将数据先写入Change Buffer中,等未来数据被读取时,再将 change buffer 中的操作merge到原数据页中

也就是如果buffer pool有数据,更新buffer pool;没有的话,也不查磁盘数据,而是写入Change Buffer。通过merge操作持久化。

change buffer的使用场景

读多写少的场景,Change Buffer很有用,因为一次merge可以处理很多读操作。

而写完了立刻要查,那就会立即触发merge,也是对磁盘的读写,这样随机访问IO的次数不会减少,反而增加了change buffer的维护代价,起到了副作用。

merge触发时机
  • 读取Change buffer中记录的数据页时,会将Change buffer合并到buffer Pool 中,然后被刷新到磁盘。
  • 系统空闲或者slow shutdown时,后台master线程发起merge。
  • change buffer的内存空间用完了,后台master线程会发起merge。
  • redo log写满了,但是一般不会发生。

buffer pool的架构

分为三个链表:

  • Flush 链表 用于快速找到脏页数据,节点是控制块
  • Free 链表 用于快速找到空闲的缓存页
  • LRU链表 用于存放干净
LRU的实现

LRU链表被分为两部分,前半部分被称为young 区域,后半部分被称为old 区域

innodb_old_blocks_pc控制old区域占比,默认37%

预读的页加入到 old 区域的头部

被真正访问才插入到young区域的头部

这解决了预读失效问题

还需要提高进入young链表的门槛

只有同时满足「被访问」与「在 old 区域停留时间超过 x 秒」两个条件,才会被插入到 young 区域头部,x是由innodb_old_blocks_time参数控制的,默认1000ms

这解决了缓存污染问题

这个和操作系统的内存管理差不多,都是对LRU算法的改进,问题相同,解决方案不同

另外young 区域前面 1/4 被访问不会移动到链表头部,只有后面的 3/4被访问才会

脏页什么时候会被刷入磁盘?

不用担心,靠WAL技术和redo log日志保证

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值