搜索
首页数据库mysql教程带你了解MySQL中的数据库缓冲池(Buffer Pool)

带你了解MySQL中的数据库缓冲池(Buffer Pool)

对于使用InnoDB存储引擎的表来说,是以页为单位来管理存储空间的,作为内存和磁盘之间换入换出的基本粒度。当我们将某页从磁盘中加载到内存中,会进行磁盘I/O。而磁盘I/O的开销非常影响整体性能,如果我们直接从内存中读取相应的页,那岂不是减少了磁盘I/O带来的性能损耗,效率则会提升很多。基于此,缓冲池(Buffer Pool 出现了,那么接下来,我们就来谈谈InnoDB中的Buffer Pool。

缓冲池(Buffer Pool)

有人会想,既然缓冲池这么好,那我们将所有数据都存储到缓冲池中不就好了,不不不,缓冲池是操作系统分配的一片连续的内存。而内存相比于磁盘的容量小得多,并且价格昂贵。那么操作系统会给缓冲池分配多少内存呢?

  • 默认情况下,缓冲池的大小为128MB;

当然,如果你的机器的内存容量非常大,可以在配置文件中配置启动选项参数innodb_buffer_pool_size单位是字节,最小不能小于5MB。

缓冲池的内部结构

缓冲池将操作系统分配的这一片连续的内存,划分成若干个大小默认为16KB的页(缓冲页)【此时还没有真正的磁盘页被缓存到Buffer Pool中】,当我们从磁盘中换入一个页到缓冲池中,如何分配位置呢?因此就需要一些控制信息来标识这些缓冲池中的缓冲页,这些控制信息都存放在一个叫控制块的内存区域中,与缓冲页一一对应。控制块的大小也是固定的。因此在这片连续的内存空间中,难免会产生内存碎片。综上,缓冲池的内部结构如下:

  • 缓冲页
  • 控制块:页号、缓冲页在缓冲池中的地址、链表节点信息等。
  • 内存碎片【若内存分配得当,内存碎片可有可无】

image-20230207185817685.png

缓冲池的管理

上面在控制块中提到了链表节点信息,那么链表节点是用来做什么的呢?是为了更好的管理缓冲池中的页。而链表就是用来链接控制块的,因为控制块与缓冲页是一一对应的。

1)空闲链表

将所有空闲的缓冲页对应的控制块链接起来,形成的链表。

解决的问题:从磁盘中换入一个页到缓冲池中,如何区分缓冲池中的哪个页是空闲的呢?而有了空闲链表之后,换入一个磁盘页到缓冲池中时,就直接从空闲链表中获取一个空闲的缓冲页,并将磁盘页中对应的信息填到缓冲页对应的控制块中,然后将该控制块从空闲链表中删除即可。

2)更新链表

若修改了缓冲池中的缓冲页的数据,导致其与磁盘中数据不一致,该页称为脏页。将所有脏页对应的控制块链接起来形成更新链表,在将来的某个时间根据该链表将对应缓存页的数据刷新到磁盘中。

3)LRU链表

缓冲池的大小是有限的,如果缓存的页超出了缓冲池的大小,即没有空闲的缓冲页了,当有新的页要添加到缓冲池中时,采取LRU的策略将旧的缓冲页从缓冲池中移除,然后将新的页添加进来。由于LRU链表涉及的内容较多,我们接下来单独介绍。

LRU链表所蕴含的“哲理”

先提一下预读机制

在I/O上的优化机制,预读顾名思义,会异步地把某些页面加载到缓冲池中,预计很快就会需要这些页面,这些请求在一个范围内引入所有页面,就是所谓的 局部性原理,目的是减少磁盘I/O。

了解预读机制之前,先回顾一下InnoDB逻辑存储单元:表空间(tablespace)→段(segment )→区(extent)→页(page)。其中特意提一下区,后面会用到:一个区就是物理位置上连续的64个页,即一个区的大小是1MB.

image-20230207175618986.png

预读机制可以细分为以下两种:

  • Linear read-ahead(线性预读):一种基于按顺序访问的缓冲池中的页面来预测可能很快需要哪些页面的技术。通过配置参数innodb_read_ahead_threshold,若顺序访问的某个区的页面超过这个参数的值,会触发异步读请求来读取下一个区中全部的页面到缓冲池中。
  • Random read-ahead(随机预读):可以根据缓冲池中已经存在的页面预测何时可能需要页面,而不管这些页面的读取顺序如何。如果在缓冲池中发现同一个区段的13个连续页面,InnoDB会异步发出一个请求来预取该区段的剩余页面。通过配置变量innodb_random_read_ahead来控制随机读的。

传统LRU对缓冲页是如何管理的呢?

利用LRU算法对最近最少使用的缓冲页进行管理,形成对应的链表,方便用于淘汰。

当访问一个页【即最近访问】

  • 该页在缓冲池中,将对应控制块移至LRU链表头部
  • 该页不在缓冲池中,淘汰尾部最近最少使用的页,从磁盘中加载进来该页并放在LRU链表头部

那么为什么InnoDB不使用这么直观的LRU算法呢?原因如下:

  1. 预读失效

    预读到缓冲池中的页都会放到LRU链表的头部,但其中很多页可能并不会被读取。

  2. 缓冲池污染

    很多使用频率较低的页加载到缓冲池中,会把使用频率较高的页从缓冲池中淘汰掉。比如全表扫描

优化后的LRU对缓冲页是如何管理的呢?

基于上述缺点,优化后的具体方法将传统LRU链表划分为两部分:热数据区域【年轻区】&冷数据区域【老年区】

  • 热数据区域【年轻区】:使用频率高的缓冲页
  • 冷数据区域【老年区】:使用频率低的区域

结构简图如下所示:

如图所示,热数据区域与冷数据区域分别占用不同比例,那么我们可以通过innodb_old_blocks_pct启动选项来控制冷数据区域所占比例。

image-20230207185041838.png

改进后的LRU如何更好的解决预读失效问题呢?

  • 某个页在初次加载到缓冲池中时,先淘汰掉冷数据区域尾部的控制块(即其对应的页淘汰掉),然后新页对应的控制块会先放到冷数据区域的头部。
  • 若后续该页不被进行访问就会慢慢从冷数据区域中被淘汰掉,总体不会影响热数据区域访问频繁的缓冲页。

改进后的LRU如何更好的解决缓冲池污染问题呢?

先说结论,并没有很好的优化这个问题,原因如下【以全表扫描为例】:

  • 某个初次访问的页同样会放到冷数据区域的头部,但后续访问又会将其放到热数据区域的头部,这样同样会把访问频率较高的页给挤掉。

那么到底该如何解决缓冲池污染问题呢?

  • 缓冲池引入了冷数据区域时间窗口机制,即只有后续访问该页与第一访问该页的时间间隔大于规定的窗口值,就会将该页从冷数据区域移到热数据区域的头部。小于规定的窗口值,就不会进行移动操作。
  • 同样,窗口值可通过innodb_old_blocks_time参数【单位ms】来设置,默认1000ms,而1s会筛选掉大部分像全表扫描这样的操作。比如在一次全表扫描过程中,多次访问一个页面的时间间隔不会超过1s。

缓冲池VS查询缓存

缓冲池和查询缓存是一个东西吗?→不是

  • 缓冲池会尽量将经常使用的数据保存起来,在MySQL进行页面读操作的时候,首先会判断该页面是否在缓冲池中,如果存在就直接读取,如果不存在,就会通过内存或磁盘将页面存放到缓冲池中再进行读取。
  • 查询缓存是提前把查询结果缓存起来,这样下次不需要执行就可以直接拿到结果。需要说明的是,在MySQL中的查询缓存,不是缓存查询计划,而是查询对应的结果。命中条件苛刻,而且只要数据表发生变化,查询缓存就会失效,因此命中率低。

【相关推荐:mysql视频教程

以上是带你了解MySQL中的数据库缓冲池(Buffer Pool)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金社区。如有侵权,请联系admin@php.cn删除
MySQL与Sqlite有何不同?MySQL与Sqlite有何不同?Apr 24, 2025 am 12:12 AM

MySQL和SQLite的主要区别在于设计理念和使用场景:1.MySQL适用于大型应用和企业级解决方案,支持高性能和高并发;2.SQLite适合移动应用和桌面软件,轻量级且易于嵌入。

MySQL中的索引是什么?它们如何提高性能?MySQL中的索引是什么?它们如何提高性能?Apr 24, 2025 am 12:09 AM

MySQL中的索引是数据库表中一列或多列的有序结构,用于加速数据检索。1)索引通过减少扫描数据量提升查询速度。2)B-Tree索引利用平衡树结构,适合范围查询和排序。3)创建索引使用CREATEINDEX语句,如CREATEINDEXidx_customer_idONorders(customer_id)。4)复合索引可优化多列查询,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。5)使用EXPLAIN分析查询计划,避

说明如何使用MySQL中的交易来确保数据一致性。说明如何使用MySQL中的交易来确保数据一致性。Apr 24, 2025 am 12:09 AM

在MySQL中使用事务可以确保数据一致性。1)通过STARTTRANSACTION开始事务,执行SQL操作后用COMMIT提交或ROLLBACK回滚。2)使用SAVEPOINT可以设置保存点,允许部分回滚。3)性能优化建议包括缩短事务时间、避免大规模查询和合理使用隔离级别。

在哪些情况下,您可以选择PostgreSQL而不是MySQL?在哪些情况下,您可以选择PostgreSQL而不是MySQL?Apr 24, 2025 am 12:07 AM

选择PostgreSQL而非MySQL的场景包括:1)需要复杂查询和高级SQL功能,2)要求严格的数据完整性和ACID遵从性,3)需要高级空间功能,4)处理大数据集时需要高性能。PostgreSQL在这些方面表现出色,适合需要复杂数据处理和高数据完整性的项目。

如何保护MySQL数据库?如何保护MySQL数据库?Apr 24, 2025 am 12:04 AM

MySQL数据库的安全可以通过以下措施实现:1.用户权限管理:通过CREATEUSER和GRANT命令严格控制访问权限。2.加密传输:配置SSL/TLS确保数据传输安全。3.数据库备份和恢复:使用mysqldump或mysqlpump定期备份数据。4.高级安全策略:使用防火墙限制访问,并启用审计日志记录操作。5.性能优化与最佳实践:通过索引和查询优化以及定期维护兼顾安全和性能。

您可以使用哪些工具来监视MySQL性能?您可以使用哪些工具来监视MySQL性能?Apr 23, 2025 am 12:21 AM

如何有效监控MySQL性能?使用mysqladmin、SHOWGLOBALSTATUS、PerconaMonitoringandManagement(PMM)和MySQLEnterpriseMonitor等工具。1.使用mysqladmin查看连接数。2.用SHOWGLOBALSTATUS查看查询数。3.PMM提供详细性能数据和图形化界面。4.MySQLEnterpriseMonitor提供丰富的监控功能和报警机制。

MySQL与SQL Server有何不同?MySQL与SQL Server有何不同?Apr 23, 2025 am 12:20 AM

MySQL和SQLServer的区别在于:1)MySQL是开源的,适用于Web和嵌入式系统,2)SQLServer是微软的商业产品,适用于企业级应用。两者在存储引擎、性能优化和应用场景上有显着差异,选择时需考虑项目规模和未来扩展性。

在哪些情况下,您可以选择SQL Server而不是MySQL?在哪些情况下,您可以选择SQL Server而不是MySQL?Apr 23, 2025 am 12:20 AM

在需要高可用性、高级安全性和良好集成性的企业级应用场景下,应选择SQLServer而不是MySQL。1)SQLServer提供企业级功能,如高可用性和高级安全性。2)它与微软生态系统如VisualStudio和PowerBI紧密集成。3)SQLServer在性能优化方面表现出色,支持内存优化表和列存储索引。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)