Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

17.5.1 缓冲池

缓冲池是InnoDB在主内存中缓存表和索引数据的地方,以便快速访问。缓冲池允许频繁使用的数据直接从内存中访问,从而加速处理。在专用服务器上,通常将物理内存的80%分配给缓冲池。

为了高效地执行大量读取操作,缓冲池被分割成可以容纳多行的页面。为了高效地管理缓存,缓冲池被实现为一个链表的页面;不常用的数据使用一种变体的最近最少使用(LRU)算法被逐出缓存。

了解如何利用缓冲池来保持频繁访问的数据在内存中是一个重要的MySQL调整方面。

缓冲池 LRU 算法

缓冲池被管理为一个列表,使用一种变体的 LRU 算法。当需要添加新页面到缓冲池时,最少使用的页面被逐出,新的页面被添加到列表的中间。这中间插入策略将列表分为两个子列表:

  • 在头部,一个子列表包含最近访问的(“年轻的”)页面

  • 在尾部,一个子列表包含不太常用的页面;这些页面是逐出候选项

图 17.2 缓冲池列表

Content is described in the surrounding text.

算法将频繁使用的页面保持在新子列表中。老子列表包含不太常用的页面;这些页面是逐出候选项。

默认情况下,算法按照以下方式操作:

  • 缓冲池的 3/8 被分配给老子列表。

  • 列表的中点是新子列表的尾部和老子列表的头部的交界点。

  • 当 InnoDB 将页面读入缓冲池时,最初将其插入到中点(老子列表的头部)。页面可以被读取,因为它是用户启动的操作所需的,或者作为 InnoDB 自动执行的读取预读操作的一部分。

  • 访问老子列表中的页面使其变“年轻”,将其移到新子列表的头部。如果页面是由于用户启动的操作所需的,那么第一次访问立即发生。如果页面是由于读取预读操作所需的,那么第一次访问可能不会立即发生,或者可能根本不会发生。

  • 随着数据库的操作,缓冲池中的页面如果不被访问就会“老化”,移动到列表的尾部。页面在新子列表和老子列表中都会老化。页面在老子列表中也会老化,因为页面被插入到中点。最终,一个未使用的页面将到达老子列表的尾部并被逐出。

默认情况下,查询读取的页面立即被移到新子列表中,这意味着它们将在缓冲池中停留更长时间。例如,mysqldump 操作或 SELECT 语句没有 WHERE 子句的表扫描可以将大量数据带入缓冲池,并逐出等量的旧数据,即使新数据从不再被使用。类似地,read-ahead 背景线程加载的页面如果只被访问一次,也会被移到新子列表的头部。这些情况可能会将频繁使用的页面推到老子列表中,使其成为逐出候选项。有关优化这种行为的信息,请参见第 17.8.3.3 节,“使缓冲池扫描抵抗”第 17.8.3.4 节,“配置 InnoDB 缓冲池预读(读取预读)”

InnoDB 标准监控输出包含了缓冲池 LRU 算法操作的几个字段的信息。有关详细信息,请参见使用 InnoDB 标准监控监控缓冲池

缓冲池配置

您可以配置缓冲池的各种方面以提高性能。

使用 InnoDB 标准监控器监控缓冲池

InnoDB 标准监控器输出,可以通过 SHOW ENGINE INNODB STATUS 访问,提供了缓冲池操作的指标。在 InnoDB 标准监控器输出的 BUFFER POOL AND MEMORY 部分中可以找到缓冲池指标:

----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 2198863872
Dictionary memory allocated 776332
Buffer pool size   131072
Free buffers       124908
Database pages     5720
Old database pages 2071
Modified db pages  910
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 4, not young 0
0.10 youngs/s, 0.00 non-youngs/s
Pages read 197, created 5523, written 5060
0.00 reads/s, 190.89 creates/s, 244.94 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not
0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read
ahead 0.00/s
LRU len: 5720, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

以下表格描述了 InnoDB 标准监控器报告的缓冲池指标。

每秒平均值是在 InnoDB 标准监控器输出中报告的,基于自上次打印 InnoDB 标准监控器输出以来的时间。

表 17.2 InnoDB 缓冲池指标

Name Description
总内存分配 缓冲池的总内存分配(以字节为单位)。
数据字典内存分配 InnoDB 数据字典的总内存分配(以字节为单位)。
缓冲池大小 缓冲池的总大小(以页为单位)。
空闲缓冲区 缓冲池空闲列表的总大小(以页为单位)。
数据库页 缓冲池 LRU 列表的总大小(以页为单位)。
旧数据库页 缓冲池旧 LRU 子列表的总大小(以页为单位)。
修改的 db 页 缓冲池中当前修改的页数。
挂起的读取 缓冲池中等待读取的页数。
挂起的写入 LRU 缓冲池中等待写入的旧页数。
挂起的写入刷新列表 缓冲池中等待刷新的页数。
挂起的单页写入 缓冲池中等待独立写入的页数。
页被设为年轻 缓冲池 LRU 列表中页被设为年轻的总数(移到“新”子列表的头部)。
页未被设为年轻 缓冲池 LRU 列表中页未被设为年轻的总数(页保持在“旧”子列表中)。
每秒年轻化 缓冲池 LRU 列表中每秒访问旧页的平均次数,导致页被设为年轻。查看下表的注释以获取更多信息。
每秒非年轻化 每秒访问旧页面的缓冲池LRU列表的平均值,未使页面变年轻。请参阅下表中的注释以获取更多信息。
读取页面 从缓冲池中读取的总页数。
创建页面 在缓冲池中创建的总页数。
写入页面 从缓冲池中写入的总页数。
读取/秒 每秒缓冲池页面读取的平均数。
创建/秒 每秒缓冲池页面创建的平均数。
写入/秒 每秒缓冲池页面写入的平均数。
缓冲池命中率 从缓冲池中读取页面的命中率vs从磁盘存储中读取。
年轻化率 页面访问结果使页面变年轻的平均命中率。请参阅下表中的注释以获取更多信息。
非年轻化率 页面访问结果未使页面变年轻的平均命中率。请参阅下表中的注释以获取更多信息。
预读页面 每秒预读操作的平均数。
未访问的页面被驱逐 每秒从缓冲池中未被访问的页面被驱逐的平均数。
随机预读 每秒随机预读操作的平均数。
LRU 长度 缓冲池 LRU 列表的总大小(以页面为单位)。
unzip_LRU 长度 缓冲池 unzip_LRU 列表的长度(以页面为单位)。
I/O 总和 缓冲池 LRU 列表页面的总访问次数。
I/O 当前 当前间隔内缓冲池 LRU 列表页面的总访问次数。
I/O unzip 总和 缓冲池 unzip_LRU 列表页面的总解压缩次数。
I/O unzip 当前 当前间隔内缓冲池 unzip_LRU 列表页面的总解压缩次数。

注释:

  • youngs/s 指标仅适用于旧页面。它基于页面访问次数。可以对同一页进行多次访问,所有这些访问都将被计数。如果您看到非常低的 youngs/s 值,而没有大型扫描正在发生,请考虑减少延迟时间或增加缓冲池中旧子列表的百分比。增加百分比将使旧子列表变大,从而增加这些页面被再次访问并变年轻的可能性。请参阅 第 17.8.3.3 节,“使缓冲池扫描抵抗”

  • non-youngs/s 指标仅适用于旧页面。它基于页面访问次数。可以对同一页进行多次访问,所有这些访问都将被计数。如果您没有看到更高的 non-youngs/s 值,而您正在执行大型表扫描(并且看到更高的 youngs/s 值),请增加延迟值。请参阅 第 17.8.3.3 节,“使缓冲池扫描抵抗”

  • young-making 率考虑了所有缓冲池页面访问,而不仅仅是旧子列表中的页面访问。 young-making 率和 not 率通常不加起来等于总缓冲池命中率。旧子列表中的页面命中会使页面移到新子列表,但新子列表中的页面命中只会使页面移到列表头部,如果它们距头部有一定距离。

  • not (young-making rate) 是页面访问未使页面变年轻的平均命中率,因为 innodb_old_blocks_time 未被满足,或者因为新子列表中的页面命中未使页面移到头部。

缓冲池 服务器状态变量INNODB_BUFFER_POOL_STATS 表提供了许多与 InnoDB 标准监控输出相同的缓冲池指标。有关更多信息,请参阅 示例 17.10,“查询 INNODB_BUFFER_POOL_STATS 表”