14.5.1 缓冲池

缓冲池是主存储器中的一个区域,InnoDB在访问 table 和索引数据时会对其进行缓存。缓冲池允许直接从内存中处理经常使用的数据,从而加快了处理速度。在专用服务器上,通常将多达 80%的物理内存分配给缓冲池。

为了提高大容量读取操作的效率,缓冲池被分为pages,它们可以潜在地容纳多行。为了提高缓存 Management 的效率,缓冲池被实现为页面的链接列 table。使用LRU算法的变体将很少使用的数据从缓存中老化掉。

知道如何利用缓冲池将经常访问的数据保留在内存中是 MySQL 优化的重要方面。

缓冲池 LRU 算法

缓冲池使用最近最少使用(LRU)算法的变体作为列 table 进行 Management。当需要空间以将新页面添加到缓冲池时,将驱逐最近使用最少的页面,并将新页面添加到列 table 的中间。此中点插入策略将列 table 视为两个子列 table:

  • 最前面是最近访问过的新(“年轻”)页面的子列 table

  • 在末尾,是最近访问过的旧页面的子列 table

图 14.2 缓冲池列 table

内容在周围的 Literals 中描述。

该算法将大量页面保留在新的子列 table 中。旧的子列 table 包含较少使用的页面。这些页面是eviction的候选页面。

默认情况下,该算法的操作如下:

  • 缓冲池的 3/8 专用于旧的子列 table。

  • 列 table 的中点是新子列 table 的尾部与旧子列 table 的头相交的边界。

  • InnoDB将页面读入缓冲池时,它最初将其插入中点(旧子列 table 的头部)。可以读取页面,因为它是用户启动的操作(例如 SQL 查询)所必需的,或者是InnoDB自动执行的read-ahead操作的一部分。

  • 访问旧子列 table 中的页面会使其“年轻”,并将其移至新子列 table 的开头。如果由于用户启动的操作而需要读取页面,则将立即进行首次访问,并使页面年轻。如果由于预读操作而读取了该页面,则第一次访问不会立即发生,并且在退出该页面之前可能根本不会发生。

  • 随着数据库的运行,通过移至列 table 的末尾,未访问缓冲池中的页面“变旧”。新的和旧的子列 table 中的页面都会随着其他页面的更新而老化。随着将页面插入中点,旧子列 table 中的页面也会老化。最终,未使用的页面到达旧子列 table 的尾部并被逐出。

默认情况下,查询读取的页面会立即移入新的子列 table,这意味着它们在缓冲池中停留的时间更长。例如,针对mysqldump操作或不具有WHERE子句的SELECT语句执行的 table 扫描可以将大量数据带入缓冲池,并逐出相同数量的旧数据,即使不再使用新数据也是如此。 。同样,由预读后台线程加载且仅访问一次的页面将移至新列 table 的开头。这些情况可能会将常用页面推送到旧的子列 table,在此它们将被逐出。有关优化此行为的信息,请参见第 14.8.3.3 节“使缓冲池扫描具有抵抗力”第 14.8.3.4 节“配置 InnoDB 缓冲池预取(预读)”

InnoDB Standard Monitor 的输出在BUFFER POOL AND MEMORY部分中包含几个与缓冲池 LRU 算法的操作有关的字段。有关详细信息,请参见使用 InnoDB 标准监视器监视缓冲池

缓冲池配置

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

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

可以使用显示引擎的 INNODB 状态进行访问的InnoDB Standard Monitor 输出提供有关缓冲池操作的度量。缓冲池度量标准位于InnoDB Standard Monitor 输出的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]

下 table 描述了InnoDB Standard Monitor 报告的缓冲池 Metrics。

Note

InnoDB Standard Monitor 输出中提供的每秒平均值基于自上次打印InnoDB Standard Monitor 输出以来经过的时间。

table14.2 InnoDB 缓冲池 Metrics

NameDescription
分配的总内存为缓冲池分配的总内存(以字节为单位)。
分配的字典内存InnoDB数据字典分配的总内存,以字节为单位。
缓冲池大小分配给缓冲池的页面总大小。
Free buffers缓冲池空闲列 table 的页面总大小。
Database pages缓冲池 LRU 列 table 的页面总大小。
旧数据库页面缓冲池旧 LRU 子列 table 的页面总大小。
修改的数据库页面缓冲池中当前修改的页面数。
Pending readsawait 读入缓冲池的缓冲池页面数。
待写 LRU从 LRU 列 table 的底部开始写入的缓冲池中的旧脏页数。
await 写入刷新列 table检查点期间要刷新的缓冲池页面数。
待写单页缓冲池中暂挂的独立页面写入数。
使页面年轻化在缓冲池 LRU 列 table 中变年轻的页面总数(移至“新”页面的子列 table 的开头)。
页面不年轻缓冲池 LRU 列 table 中没有年轻的页面总数(保留在“旧”子列 table 中但没有年轻的页面)。
youngs/s每秒平均访问缓冲池 LRU 列 table 中的旧页面所导致的页面年轻。有关更多信息,请参见此 table 后面的 Comments。
non-youngs/s每秒平均访问缓冲池 LRU 列 table 中的旧页面导致的页面不年轻。有关更多信息,请参见此 table 后面的 Comments。
Pages read从缓冲池读取的页面总数。
Pages created在缓冲池中创建的页面总数。
Pages written从缓冲池写入的页面总数。
reads/s每秒平均每秒读取的缓冲池页面数。
creates/s每秒平均创建的缓冲池页面的每秒数量。
writes/s每秒平均缓冲池页面写入数。
缓冲池命中率从缓冲池内存与磁盘存储读取的页面的缓冲池页面命中率。
young-making rate页面访问的平均命中率使页面更年轻。有关更多信息,请参见此 table 后面的 Comments。
不(成年率)页面访问未使页面变年轻的平均命中率。有关更多信息,请参见此 table 后面的 Comments。
预读页面预读操作的每秒平均数。
被逐出的页面无权访问每秒从缓冲池访问而未访问的页面的平均值。
随机预读随机预读操作的每秒平均数。
LRU len缓冲池 LRU 列 table 的页面总大小。
unzip_LRU len缓冲池 unzip_LRU 列 table 的页面总大小。
I/O sum最近 50 秒内访问的缓冲池 LRU 列 table 页面的总数。
I/O cur已访问的缓冲池 LRU 列 table 页面的总数。
I/O 解压缩总和已访问的缓冲池 unzip_LRU 列 table 页面的总数。
I/O 解压缩已访问的缓冲池 unzip_LRU 列 table 页面的总数。

Notes :

  • youngs/sMetrics 仅适用于旧页面。它基于对页面的访问次数而不是页面数。可以对给定页面进行多次访问,所有访问都计入在内。如果没有大扫描时看到的youngs/s值很低,则可能需要减少延迟时间或增加用于旧子列 table 的缓冲池百分比。增加百分比会使旧的子列 table 变大,因此该子列 table 中的页面需要更长的时间才能移到尾部,这增加了再次访问这些页面并使它们变年轻的可能性。

  • non-youngs/sMetrics 仅适用于旧页面。它基于对页面的访问次数而不是页面数。可以对给定页面进行多次访问,所有访问都计入在内。如果执行大型 table 扫描时看不到较高的non-youngs/s值(和较高的youngs/s值),请增加延迟值。

  • young-making计费用于访问所有缓冲池页面,而不仅仅是访问旧子列 table 中的页面。 young-making速率和not速率通常不会加总到整个缓冲池命中率。旧子列 table 中的页面命中会导致页面移动到新的子列 table,但是新子列 table 中的页面命中只会导致页面与列 table 的头部保持一定距离时才移动到列 table 的头部。

  • not (young-making rate)是由于未满足innodb_old_blocks_time所定义的延迟,或者由于新子列 table 中的页面点击未导致页面移动到头部而导致页面访问未使页面变年轻的平均点击率。此速率说明了对所有缓冲池页面的访问,而不仅仅是访问旧子列 table 中的页面。

缓冲池服务器状态变量INNODB_BUFFER_POOL_STATStable 提供了与InnoDB Standard Monitor 输出中许多相同的缓冲池度量标准。有关更多信息,请参见示例 14.10“查询 INNODB_BUFFER_POOL_STATStable”