当前位置: 首页 > ai >正文

innoDB的buffer pool

innoDB

分为内存结构和磁盘结构两个部分,其中内存结构的主要部分是buffer pool。

buffer pool

innoDB的内存架构的主要部分

本质与作用

buffer pool是innoDB引擎内的一个重要组件,是一个内存缓存,它的性能直接影响到innoDB的表现。通过缓存数据和索引,将磁盘 I/O 转化为内存操作,使 CRUD 操作从 毫秒级(磁盘) 降至 微秒级(内存)。合理配置 Buffer Pool 大小、实例数和刷盘策略,是优化 MySQL 性能的关键步骤。

作用:缓存磁盘上的表数据页(data page)和索引页(index page),减少磁盘 I/O。

读的大概流程:查询到某个buffer pool实例,使用哈希算法找到要查取的数据,查取,然后返回,如果没查到,去磁盘查,读到buffer pool中。 写的大概流程:先把数据和日志写入 buffer pool 和 log buffer,再由后台线程以一定频率将 buffer 中的内容刷到磁盘,「这个刷盘机制叫做Checkpoint」

大致的查询流程如下:[1]

内部结构

Buffer Pool的本质就是一大块内存数据结构,由多个缓存页和其控制块组成,另外配套的各种链表数据结构(free、flush、LRU)来辅助执行引擎的运行。

结构:

Buffer Pool 通过 数据页(缓存页) + 控制块 的组合存储数据,利用 Free/LRU/Flush 链表 管理页的生命周期,结合 哈希表 加速访问,并通过 多实例与 Chunk 优化高并发场景。其设计核心是平衡内存利用率、访问效率和数据一致性,是 InnoDB 实现高性能的关键。

存储数据

由 缓存页+控制块 构成,数据存在缓存页中,控制块存这个缓存页的元信息[2]。 在Buffer Pool中,每个缓存页的控制块放在最前面,然后各个缓存页放在后面,大概如下图所示:[3],[4]

Buffer Pool默认大小 128M,用于缓存数据页(16KB),控制块大小约800个字节(不到1KB)。所以配置 innodb_buffer_pool_size=128M 时,InnoDB 实际会申请约 134MB 内存(多出的 6MB 用于控制块)。

free链表

当需要加载新的缓存页时,执行引擎是如何知道哪些缓存页是空闲的呢?

答案是使用free链表对空白缓存页进行管理,在Buffer Pool中会有一个双向链表数据结构的free链表。在这个链表中存储的每个节点是一个空闲缓存页的控制块的地址。只要存在一个缓存页是空闲的,此时对应的控制块就会被放入这个free链表中。

flush链表

如果一个缓存页被写了,那么这页就成为脏页,flush链表就是记录脏页的。其原理和free链表一样,只不过存的是脏页而不是空白页。

LRU链表

成熟的缓存都有这个机制,不然只进数据不出数据,是不现实的。 这里的lru链表和其他的lru链表也没什么不同,都是只要被查取了,就放到前面去,淘汰就拿最后的。

冷热分离策略

MySQL会预读多一些的数据,多出来的数据,不能算是热点数据,如果放到链表前面,把后面的真热点数据挤出去了,是很不好的事情。这里lru会采用冷热分离的策略,大致思路就是把真热点数据放到前面,预读来的非热点的数据放到后面。冷热数据的比例是由参数innodb_old_blocks_pct参数控制的,默认配置为37,代表了冷数据占比37%

简答:

  • 将 LRU 链表分为两部分:

    • new 区(热数据区):占 63%

    • old 区(冷数据区):占 37%

  • 新数据从 midpoint(冷数据区头部)插入

  • 数据页在 old 区停留时间超过 innodb_old_blocks_time(默认 1s)后,再次访问才会移到 new 区19

哈希表

MySQL如何知道一个数据页是否被缓存?答案是使用哈希表。 这个哈希表的key采用表空间号和数据页号组成,value存储缓存页地址。

脏页-刷盘持久化

通过对上述三种链表的描述,我们知道「当我们对数据进行修改时,其实修改的是Buffer Pool 中数据所在缓存页,修改后将其设置为脏页,并将脏页的控制块同时存在于 LRU 链表和 Flush 链表」。然后通过刷脏将修改同步至磁盘[5]。

刷脏不是每次修改都进行的,那样性能会很差,因此刷脏是通过一定的时机触发进行批量刷盘的。

脏页的刷盘时机总的来说就分为以下种:

  • redo log 日志满了的情况下,会主动触发脏页刷新到磁盘;

  • MySQL 正常关闭之前,会把所有的脏页刷入到磁盘;

  • Buffer Pool 空间不足时,会淘汰一部分数据页,如果淘汰的是脏页,需要先将其同步到磁盘。

  • MySQL 空闲时,后台线程会定期脏页刷盘

--

注释&引用

[1]MySQL缓冲池(buffer pool),这次终于懂了_mysql bufferpool-CSDN博客
[2]缓存页原信息指的是当前缓存页所对应的表空间数据页编号、当前缓存页在Buffer Pool中的地址信息等。
[3]所有相似风格的图中所有《描述数据》都为文中的《控制块》
[4]04.MySQL InnoDB Buffer Pool深度解析 - 《MySQL》 - 极客文档
[5]MySQL十六:36张图理解Buffer Pool - 云扬四海 - 博客园

http://www.xdnf.cn/news/16855.html

相关文章:

  • 2025熵密杯 -- 初始谜题 -- Reproducibility
  • sqli-labs:Less-19关卡详细解析
  • 交互 Codeforces Round 1040 Interactive RBS
  • 网易云音乐硬刚腾讯系!起诉SM娱乐滥用市场支配地位
  • 联合索引全解析:一棵树,撑起查询的半边天
  • Anthropic:跨越生产效能拐点的AI增长飞轮
  • Linux学习--数据结构
  • 牛客 - 旋转数组的最小数字
  • MySQL 内置函数
  • Anthropic最新研究Persona vector人格向量
  • Python正则表达式使用指南:从基础到实战
  • 2025.8.2
  • VScode对Ubuntu用root账号进行SSH远程连接开发
  • 文心4.5开源测评:国产大模型的轻量化革命与全栈突破
  • 每日五个pyecharts可视化图表-bars(1)
  • SpringBoot启动项目详解
  • 详解Python标准库之命令行界面库
  • JavaScript特殊集合WeakMap 的使用及场景介绍
  • 未来交通:元宇宙技术重塑出行体验
  • SLAM中的非线性优化-2D图优化之零空间实战(十六)
  • Selenium自动化:轻松实现网页操控
  • 归并排序(简单讲解)
  • MySQL 基础
  • linux source命令使用详细介绍
  • 浅拷贝与深拷贝的区别
  • Vue 响应式基础全解析2
  • Python Pandas.unique函数解析与实战教程
  • 24黑马SpringCloud的Docker本地目录挂载出现相关问题解决
  • 《JMM 与 happens-before 原则:并发编程的核心内存语义》
  • 网络常识-子网掩码