什么是MySQL的"内存数据加速器"——Buffer Pool?

数据库 MySQL
InnoDB 还采用了一种适应性刷新算法,根据 redo log 的生成速度和当前的刷新率动态调整刷新速度。其目的是通过确保刷新活动与当前工作负载保持同步,来平滑整体性能。

我们都知道,MySQL 的数据(除了 Memory 引擎外)都存储在磁盘上。然而,若每次查询和修改都直接与磁盘交互,性能将会非常低下。

因此,为了提升读写性能,Innodb 引擎引入了一个中间层,即缓冲池(buffer pool)。

缓冲池是内存中一块连续的空间,主要用于缓存数据页。每个数据页的大小为 16KB。

页是 Innodb 进行数据存储的基本单元,无论是在磁盘还是在缓冲池中,数据的读取都是以页为单位进行的,这也体现了一种“预读”的思想。

图片图片

有了缓冲池之后,当我们进行数据查询时,InnoDB 会首先检查缓冲池中是否存在该数据。如果存在,数据就可以直接从内存中获取,避免了频繁的磁盘读取,从而提高查询性能。如果不存在,则会去磁盘中读取数据,并将找到的数据页复制到缓冲池中,再返回给客户端。这样,后续的查询可以直接从缓冲池中就近读取数据。

图片图片

当需要进行数据修改时,操作也会先在缓冲池中进行,然后再将修改后的数据写入磁盘。

然而,由于缓冲池是基于内存的,其空间不可能无限大,默认大小为 128M。当然,这个大小并不是固定的,我们可以通过修改 MySQL 配置文件中的 innodb_buffer_pool_size 参数来调整缓冲池的大小。

# 查看buffer pool
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';


# 修改buffer pool
SET GLOBAL innodb_buffer_pool_size = 512M;

扩展知识

InnoDB 的数据页

上面提到了 InnoDB 的数据页,它和 B+树的关系是怎样的呢?

InnoDB 的数据页是其存储引擎中用于存储数据的基本单位。数据页在磁盘上是一个连续的区域,通常大小为 16KB,当然也可以通过配置进行调整。16KB 意味着 InnoDB 的每次读写操作都是以 16KB 为单位的,即一次从磁盘读取到内存的最小单位是 16KB,从内存写入到磁盘的最小单位也是 16KB。

在 B+树结构中,每个节点都对应着一个数据页,包括根节点、非叶子节点和叶子节点。B+树通过节点之间的指针连接不同层级的数据页,从而构建出一个有序的索引结构。

图片图片

通过 B+树的搜索过程,可以从根节点开始逐层遍历,最终到达叶子节点,找到所需的数据行。

因此,数据页是存储数据行的实际物理空间,以页为单位进行磁盘读写操作。B+树通过节点和指针的组织,构建了一个层次结构的索引,用于快速定位和访问数据行。

B+树的非叶子节点对应着数据页,其中存储着主键及指向子节点(即其他数据页)的指针。B+树的叶子节点包含实际的数据行,每个数据行存储在一个数据页中。

通过这种方式,InnoDB 利用 B+树和数据页的组合,实现了高效的数据存储和检索。B+树提供了快速的索引查找能力,而数据页提供了实际存储和管理数据行的机制。它们相互配合,使得 InnoDB 能够处理大规模数据的高效访问。

数据页的构成

一个数据页包含七个部分,分别是文件头、页头、最小和最大记录、用户记录、空闲空间、页目录以及文件尾。

图片图片

buffer pool 和 query cache 的区别

在 InnoDB 中,除了缓冲池(Buffer Pool),还有另一个缓存层用于数据缓存,提升查询效率。很多人容易混淆它与缓冲池的区别。

首先,它们的目的和作用不同。缓冲池用于缓存表和索引的数据页,从而加速读取操作;而查询缓存(Query Cache)用于缓存查询结果,减少重复查询的执行时间。

缓冲池主要与存储引擎 InnoDB 相关,而查询缓存也支持其他引擎,如 MyISAM 等。因此,查询缓存位于服务器层的优化技术,而缓冲池位于引擎层的优化技术。

需要注意的是,在 MySQL 5.7 版本中,查询缓存已经被标记为废弃,并在 MySQL 8.0 版本中彻底被移除。

buffer pool 的读写过程是怎么样的?

MySQL 的缓冲池(Buffer Pool)是一个内存区域,用于缓存数据页,从而提高查询性能。读写过程涉及将数据从磁盘读取到内存、在内存中进行修改,并最终写回磁盘。

读过程

当我们在 MySQL 执行一个查询请求时,其过程如下:

  1. MySQL 首先检查缓冲池(Buffer Pool)中是否存在本次查询的数据。如果数据在缓冲池中,就直接返回结果。
  2. 如果数据不在缓冲池中,MySQL 会从磁盘读取数据。
  3. 读取的数据页被放入缓冲池,同时 MySQL 会将请求的数据返回给应用程序。

读取过程相对简单,而缓冲池的写入过程则稍显复杂。

写过程

当执行一次更新语句(如 INSERT、UPDATE 或 DELETE)时,MySQL 的过程如下:

  1. 应用程序执行写操作时,MySQL 首先将要修改的数据页加载到缓冲池(Buffer Pool)中。
  2. 在缓冲池中,对数据页进行修改,以满足写请求。这些修改只在内存中进行,不会立即写回磁盘。
  3. 如果缓冲池中的数据页被修改过,MySQL 会将这个页标记为“脏页”(Dirty Page)。
  4. 脏页会被后台线程写回磁盘,这个过程称为脏页刷盘。写入操作完成后,数据得以持久化。

需要注意的是,脏页的写回磁盘是由后台线程进行的。在 MySQL 服务器空闲或负载较低时,InnoDB 会执行脏页刷盘操作,以减少对用户线程的影响,从而降低性能的影响。

参考文档:https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool-flushing.html

图片图片

当脏页的百分比达到innodb_max_dirty_pages_pct_lwm变量定义的低水位标记时,将启动缓冲池的刷新。缓冲池页的默认低水位标记为 10%。将innodb_max_dirty_pages_pct_lwm值设为 0 会禁用这种提前刷新行为。

InnoDB 还采用了一种适应性刷新算法,根据 redo log 的生成速度和当前的刷新率动态调整刷新速度。其目的是通过确保刷新活动与当前工作负载保持同步,来平滑整体性能。

当然,我们也可以通过执行SET GLOBAL innodb_buffer_pool_dump_now=ON来手动触发脏页刷新到磁盘。

此外,在 MySQL 服务器正常关闭或重启时,所有的脏页都会被刷新到磁盘,以确保数据持久化。

责任编辑:武晓燕 来源: 码上遇见你
相关推荐

2022-07-07 11:51:15

比特币区块链加密货币

2022-01-12 09:09:30

数据库信息化加速器

2021-03-01 18:37:15

MySQL存储数据

2011-08-30 10:37:43

CDN

2022-03-22 15:05:15

MySQL缓冲池

2009-03-30 09:08:40

微软浏览器IE8

2023-10-07 15:56:49

三链表缓存页flush链表

2024-06-04 09:42:08

2024-10-23 08:47:46

2014-11-24 11:10:09

大数据

2014-11-26 13:34:53

大数据

2011-10-31 15:58:24

应用评估服务

2024-05-31 13:05:34

2020-07-20 10:32:43

暗网网络安全网络攻击

2020-02-19 10:10:41

AI基因分析人工智能

2018-01-19 15:42:17

戴尔

2018-10-17 14:15:37

赛灵思ACAP
点赞
收藏

51CTO技术栈公众号