MySQL InnoDB 缓冲池 buffer pool

什么是buffer pool

MySQL服务器启动的时候会向操作系统申请了一片连续的内存作为缓冲池(buffer pool),默认128M,可以通innodb_buffer_pool_size过来调整它的大小。用于缓存表数据与索引数据,把磁盘上的数据页加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用。

buffer pool中存有控制块和缓存页一一对应,控制块包含:缓存页所属的表空间编号、页号、缓存页在buffer pool中的地址、链表节点信息、一些锁信息以及LSN信息;缓存页和磁盘上默认的页大小一样都是16K。

预读

MySQL是以页(16K)为单位读取磁盘数据放入buffer pool的,按页读取不仅能提高性能,还遵守“集中读写”的原则能把一些“可能要访问”的页提前加入缓冲池,避免未来的磁盘IO操作。

LRU链表

MySQL是用LRU(Least recently used)算法来管理这些缓存页的。并将LRU链表分为young和old两个区域。首次从磁盘上加载到buffer pool的页放到老年代头部,如果数据被访问则加到新生代的头部;如果数据没被访问则会被逐渐移到老年代尾部直到淘汰。

注意:在一定时间内访问初次加载到buffer pool的页不会被加到新生代的头部,这个时间由innodb_old_blocks_time变量控制。这是针对全表扫描时,短时间内访问大量使用频率非常低的页面情况的优化。

flush链表

如果修改了buffer pool中某个缓存页的数据,那它就和磁盘上的页不一致了,这样的缓存页被称为脏页(dirty page)。

buffer pool内创建一个存储脏页的链表,凡是修改过的缓存页对应的控制块都会作为一个节点加入到一个链表中,因为这个链表节点对应的缓存页都是需要被刷新到磁盘上的,所以也叫flush链表。

写缓冲(change buffer)

当要写的数据页不在缓冲池时,将缓冲变更(buffer changes)记录在缓冲池,未来数据被读取时,再将数据合并(merge)恢复到缓冲池中。

写缓冲只适用非唯一索引,因为唯一索引需要检查唯一性。

刷盘

后台有专门的线程每隔一段时间负责把脏页刷新到磁盘,这样可以不影响用户线程处理正常的请求。主要有两种刷新路径:

  1. 从LRU链表的冷数据中刷新一部分页面到磁盘:后台线程会定时从LRU链表尾部开始扫描一些页面,如果从里边儿发现脏页,会把它们刷新到磁盘。这种刷新页面的方式被称之为BUF_FLUSH_LRU。
  2. 从flush链表中刷新一部分页面到磁盘:后台线程也会定时从flush链表中刷新一部分页面到磁盘,刷新的速率取决于当时系统是不是很繁忙。这种刷新页面的方式被称之为BUF_FLUSH_LIST。

当后台线程刷新脏页的进度比较慢,处理用户请求时,没有可用空间加载新的缓存页时,会在线刷盘,降低处理用户请求的速度。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值