Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


17.5.1 缓冲池

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

为了提高高容量读操作的效率,缓冲池被分割成可以存储多行的页面。为了提高缓存管理的效率,缓冲池实现为页面链表;数据较少使用的数据将使用最少最近使用(LRU)算法的变体从缓存中淘汰。

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

缓冲池 LRU 算法

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

  • 在头部,一组新的(young) 页面,最近访问过

  • 在尾部,一组老页面,访问频率较低

图17.2 缓冲池列表

Content is described in the surrounding text.

算法将频繁使用的页面保留在新子列表中。老子列表包含较少使用的页面;这些页面是候选项,可能会被淘汰

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

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

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

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

  • 访问老子列表中的页面将其标记为““young””,将其移动到新子列表头部。如果页面是因为用户启动的操作而被读取,那么第一个访问将立即发生并将页面标记为young。如果页面是由于预读操作而被读取,那么第一个访问可能不会立即发生,也可能在页面被驱逐前不再发生。

  • 随着数据库的运行,缓冲池中的页面如果没有被访问将““age””,向列表尾部移动。新子列表和老子列表中的页面都将因其他页面被标记为new而变得老。老子列表中的页面也将因页面在中点插入而变得老。最终,如果一个页面保持未使用状态,将到达老子列表的尾部并被驱逐。

默认情况下,查询读取的页面将立即移动到新的子列表中,这意味着它们在缓冲池中停留更长时间。例如,对于一个没有WHERE子句的SELECT语句或mysqldump操作,可能会将大量数据加载到缓冲池中,并驱逐等量的 older 数据,即使新数据再也不会被使用。类似地,读取背景线程加载的页面,如果只访问一次,就会移动到新的列表头部。这类情况可以推动频繁使用的页面到老子列表中,使它们变得易于驱逐。有关优化这种行为的信息,请见第17.8.3.3节,“使缓冲池扫描 resistant”第17.8.3.4节,“配置InnoDB缓冲池预取(读取前)”

InnoDB标准监控器输出的BUFFER POOL AND MEMORY部分包含了缓冲池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列表中页面总数。
老数据库页面 缓冲池old LRU子列表中的页面总数。
修改的数据库页面 当前缓冲池中已修改的页面数量。
等待读取 缓冲池中等待被读入的页面数量。
LRU pending writes 缓冲池中的老脏页面,需要从LRU列表底部写回的数量。
flush list pending writes checkpointing期间需要被刷新的缓冲池页面数量。
单页pending writes 缓冲池中独立写入的pending页面数量。
Pages made young 缓冲池LRU列表中的总young页面数量(从“new”子列表移动到头部)。
Pages made not young 缓冲池LRU列表中的总不young页面数量(在“old”子列表中没有被young的页面)。
youngs/s 每秒平均访问老页面的次数,结果使页面young。请参阅以下表格注释以获取更多信息。
non-youngs/s 缓冲池LRU列表中每秒平均访问老页面的次数,未使页面年轻。请参阅以下表格后的注释以获取更多信息。
读取页数 缓冲池中总共读取的页数。
创建页数 缓冲池中创建的总页数。
写入页数 从缓冲池中写入的总页数。
每秒读取次数/s 每秒平均缓冲池页读取次数。
创建/秒 每秒平均缓冲池页创建次数。
写入/秒 每秒平均缓冲池页写入次数。
缓冲池命中率 从缓冲池读取 vs 从磁盘存储的缓冲池页命中率。
使页面年轻率 每秒平均访问页面时使页面年轻的次数。请参阅以下表格后的注释以获取更多信息。
未使页面年轻率 每秒平均访问页面时未使页面年轻的次数。请参阅以下表格后的注释以获取更多信息。
预读页数 每秒平均预读操作次数。
未访问页数 每秒平均从缓冲池中未访问的页数。
随机预读 每秒平均随机预读操作次数。
LRU列表长度 缓冲池LRU列表总大小(页数)。
unzip_LRU列表长度 缓冲池unzip_LRU列表的长度(页数)。
I/O总和 缓冲池LRU列表页总访问次数。
I/O当前 当前时间间隔内的缓冲池LRU列表页总访问次数。
I/O解压缩和 缓冲池unzip_LRU列表页总解压缩次数。
I/O当前解压缩 当前时间间隔内的缓冲池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标准监控输出中找到的一些缓冲池指标。更多信息,请见Example 17.10,“Querying the INNODB_BUFFER_POOL_STATS Table”