缓冲池是主内存中的一个区域,InnoDB在访问表和索引数据时会将其缓存到这里。缓冲池允许频繁使用的数据直接从内存访问,从而加快处理速度。在专用服务器上,通常将高达 80% 的物理内存分配给缓冲池。The buffer pool is an area in main memory where
InnoDB caches table and index data as it is
accessed. The buffer pool permits frequently used data to be
accessed directly from memory, which speeds up processing. On
dedicated servers, up to 80% of physical memory is often assigned to
the buffer pool.
为了高吞吐量读操作的效率,缓冲池被划分为可以存放多行的页。为了缓存管理的效率,缓冲池实现为页的链表;很少使用的数据会使用一种最近最少使用 (LRU) 算法的变体从缓存中逐出。For efficiency of high-volume read operations, the buffer pool is divided into pages that can potentially hold multiple rows. For efficiency of cache management, the buffer pool is implemented as a linked list of pages; data that is rarely used is aged out of the cache using a variation of the least recently used (LRU) algorithm.
了解如何利用缓冲池将频繁访问的数据保存在内存中,是 MySQL 调优的重要方面。Knowing how to take advantage of the buffer pool to keep frequently accessed data in memory is an important aspect of MySQL tuning.
缓冲池作为列表进行管理,使用 LRU 算法的变体。当需要为缓冲池添加新页腾出空间时,会驱逐最近最少使用的页,并将新页添加到列表的中间。该中点插入策略将列表视为两个子列表:The buffer pool is managed as a list using a variation of the LRU algorithm. When room is needed to add a new page to the buffer pool, the least recently used page is evicted and a new page is added to the middle of the list. This midpoint insertion strategy treats the list as two sublists:
列表头部:最近访问过的新(“年轻”)页子列表At the head, a sublist of new (“young”) pages that were accessed recently
列表尾部:较少最近访问的旧页子列表At the tail, a sublist of old pages that were accessed less recently
该算法将经常使用的页面保存在新子列表中。旧子列表包含较少使用的页面;这些页面是淘汰的候选。The algorithm keeps frequently used pages in the new sublist. The old sublist contains less frequently used pages; these pages are candidates for eviction.
默认情况下,算法的操作如下:By default, the algorithm operates as follows:
缓冲池的 3/8 用于旧子列表。3/8 of the buffer pool is devoted to the old sublist.
列表的中点是新子列表尾部与旧子列表头部的边界。The midpoint of the list is the boundary where the tail of the new sublist meets the head of the old sublist.
当
InnoDB将页面读入缓冲池时,最初会将其插入到中点位置(旧子列表的头部)。页面可能被读取,是由于用户发起的操作(如 SQL 查询)所需,或作为InnoDB自动执行的预读操作的一部分。WhenInnoDBreads a page into the buffer pool, it initially inserts it at the midpoint (the head of the old sublist). A page can be read because it is required for a user-initiated operation such as an SQL query, or as part of a read-ahead operation performed automatically byInnoDB.访问旧子列表中的页面会使其“年轻”,并将其移到新子列表的头部。如果该页面是由于用户发起的操作而被读取,第一次访问会立即发生,并且页面会被标记为年轻。如果该页面是由于预读操作而被读取,第一次访问不会立即发生,并且在页面被驱逐之前可能根本不会发生。Accessing a page in the old sublist makes it “young”, moving it to the head of the new sublist. If the page was read because it was required by a user-initiated operation, the first access occurs immediately and the page is made young. If the page was read due to a read-ahead operation, the first access does not occur immediately and might not occur at all before the page is evicted.
As the database operates, pages in the buffer pool that are not accessed “年龄” by moving toward the tail of the list. Pages in both the new and old sublists age as other pages are made new. Pages in the old sublist also age as pages are inserted at the midpoint. Eventually, a page that remains unused reaches the tail of the old sublist and is evicted.As the database operates, pages in the buffer pool that are not accessed “age” by moving toward the tail of the list. Pages in both the new and old sublists age as other pages are made new. Pages in the old sublist also age as pages are inserted at the midpoint. Eventually, a page that remains unused reaches the tail of the old sublist and is evicted.
默认情况下,通过查询读取的页面会立即移动到新的子列表中,这意味着它们会在缓冲池中停留更长时间。例如,为 mysqldump 操作或没有 WHERE 子句的 SELECT 语句执行的表扫描,可以将大量数据带入缓冲池并驱逐同等数量的旧数据,即使新数据再也不会被使用。类似地,由预读取后台线程加载并且只访问一次的页面会被移到新列表的前端。这些情况可能会将经常使用的页面推到旧子列表,从而面临被驱逐的风险。有关优化此行为的信息,请参阅 第 17.8.3.3 节,“使缓冲池抗扫描” 和 第 17.8.3.4 节,“配置 InnoDB 缓冲池预取(预读取)”。By default, pages read by queries are immediately moved into the
new sublist, meaning they stay in the buffer pool longer. A table
scan, performed for a mysqldump operation or a
SELECT statement with no
WHERE clause, for example, can bring a large
amount of data into the buffer pool and evict an equivalent amount
of older data, even if the new data is never used again.
Similarly, pages that are loaded by the read-ahead background
thread and accessed only once are moved to the head of the new
list. These situations can push frequently used pages to the old
sublist where they become subject to eviction. For information
about optimizing this behavior, see
Section 17.8.3.3, “Making the Buffer Pool Scan Resistant”, and
Section 17.8.3.4, “Configuring InnoDB Buffer Pool Prefetching (Read-Ahead)”.
InnoDB 标准监控器输出在 BUFFER POOL AND MEMORY 部分包含有关缓冲池 LRU 算法操作的多个字段。详情请参见 使用 InnoDB 标准监控器监控缓冲池。InnoDB Standard Monitor output contains several
fields in the BUFFER POOL AND MEMORY section
regarding operation of the buffer pool LRU algorithm. For details,
see Monitoring the Buffer Pool Using the InnoDB Standard Monitor.
您可以配置缓冲池的各个方面以提高性能。You can configure the various aspects of the buffer pool to improve performance.
理想情况下,您应将缓冲池的大小设置为尽可能大的值,同时留出足够的内存供服务器上的其他进程运行,以避免过度分页。缓冲池越大,
InnoDB就越像一个内存数据库,一旦从磁盘读取数据,后续读取就会从内存中访问数据。参见 第 17.8.3.1 节,“配置 InnoDB 缓冲池大小”。Ideally, you set the size of the buffer pool to as large a value as practical, leaving enough memory for other processes on the server to run without excessive paging. The larger the buffer pool, the moreInnoDBacts like an in-memory database, reading data from disk once and then accessing the data from memory during subsequent reads. See Section 17.8.3.1, “Configuring InnoDB Buffer Pool Size”.在具有足够内存的 64 位系统上,您可以将缓冲池拆分为多个部分,以最小化并发操作中对内存结构的争用。详情请参见 第 17.8.3.2 节,“配置多个缓冲池实例”。On 64-bit systems with sufficient memory, you can split the buffer pool into multiple parts to minimize contention for memory structures among concurrent operations. For details, see Section 17.8.3.2, “Configuring Multiple Buffer Pool Instances”.
无论操作是否会将大量不常访问的数据带入缓冲池,您都可以将经常访问的数据保存在内存中。详情请参阅 第 17.8.3.3 节,“使缓冲池抗扫描”。You can keep frequently accessed data in memory regardless of sudden spikes of activity from operations that would bring large amounts of infrequently accessed data into the buffer pool. For details, see Section 17.8.3.3, “Making the Buffer Pool Scan Resistant”.
您可以控制如何以及何时执行预读请求,以异步预取页面到缓冲池中,以应对即将到来的访问需求。详情请参阅 第 17.8.3.4 节,“配置 InnoDB 缓冲池预取(预读)”。You can control how and when to perform read-ahead requests to prefetch pages into the buffer pool asynchronously in anticipation of impending need for them. For details, see Section 17.8.3.4, “Configuring InnoDB Buffer Pool Prefetching (Read-Ahead)”.
您可以控制后台刷新发生的时间,以及刷新速率是否根据工作负载动态调整。有关详细信息,请参阅 第 17.8.3.5 节,“配置缓冲池刷新”。You can control when background flushing occurs and whether or not the rate of flushing is dynamically adjusted based on workload. For details, see Section 17.8.3.5, “Configuring Buffer Pool Flushing”.
您可以配置
InnoDB如何保留当前缓冲池状态,以避免在服务器重启后经历长时间的预热期。有关详细信息,请参阅 第 17.8.3.6 节,“保存和恢复缓冲池状态”。You can configure howInnoDBpreserves the current buffer pool state to avoid a lengthy warmup period after a server restart. For details, see Section 17.8.3.6, “Saving and Restoring the Buffer Pool State”.
InnoDB 标准监控器输出,可通过 SHOW
ENGINE INNODB STATUS 访问,提供有关缓冲池操作的指标。缓冲池指标位于 InnoDB 标准监控器输出的 BUFFER POOL AND MEMORY 部分:InnoDB Standard Monitor output, which can be
accessed using
SHOW
ENGINE INNODB STATUS, provides metrics regarding
operation of the buffer pool. Buffer pool metrics are located in
the BUFFER POOL AND MEMORY section of
InnoDB Standard Monitor output:
---------------------- 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 标准监控器报告的缓冲池指标。The following table describes buffer pool metrics reported by the
InnoDB Standard Monitor.
InnoDB 标准监控器输出中提供的每秒平均值是基于自 InnoDB 标准监控器上次打印以来经过的时间计算的。Per second averages provided in InnoDB Standard
Monitor output are based on the elapsed time since
InnoDB Standard Monitor output was last
printed.
表 17.2 InnoDB 缓冲池指标Table 17.2 InnoDB Buffer Pool Metrics
| 名称Name | 说明Description |
|---|---|
| 分配的总内存Total memory allocated | 缓冲池分配的总内存(以字节为单位)。The total memory allocated for the buffer pool in bytes. |
| 字典分配的内存Dictionary memory allocated | InnoDB 数据字典分配的总内存(以字节为单位)。The total memory allocated for the InnoDB data
dictionary in bytes. |
| 缓冲池大小Buffer pool size | 分配给缓冲池的总页数大小。The total size in pages allocated to the buffer pool. |
| 空闲缓冲区Free buffers | 缓冲池空闲列表的总页数。The total size in pages of the buffer pool free list. |
| 数据库页Database pages | 缓冲池 LRU 列表的总页数。The total size in pages of the buffer pool LRU list. |
| 旧数据库页Old database pages | 缓冲池旧 LRU 子列表的总页数。The total size in pages of the buffer pool old LRU sublist. |
| 已修改的数据库页Modified db pages | 缓冲池中当前已修改的页数。The current number of pages modified in the buffer pool. |
| 待读取Pending reads | 等待读取到缓冲池的缓冲池页数。The number of buffer pool pages waiting to be read into the buffer pool. |
| 待写入 LRUPending writes LRU | 缓冲池中需要从 LRU 列表底部写入的旧脏页数。The number of old dirty pages within the buffer pool to be written from the bottom of the LRU list. |
| 待写入刷新列表Pending writes flush list | 在检查点期间需要刷新的缓冲池页数。The number of buffer pool pages to be flushed during checkpointing. |
| 待写入单页Pending writes single page | 缓冲池中待独立写入的页数。The number of pending independent page writes within the buffer pool. |
| 被标记为年轻的页Pages made young | 在缓冲池 LRU 列表中被标记为新的页的总数(移动到子列表“新”页的头部)。The total number of pages made young in the buffer pool LRU list (moved to the head of sublist of “new” pages). |
| 未被标记为年轻的页Pages made not young | 在缓冲池 LRU 列表中未被标记为新的页的总数(一直保持在“旧”子列表中而未被标记为新页的页)。The total number of pages not made young in the buffer pool LRU list (pages that have remained in the “old” sublist without being made young). |
| 年轻页/秒youngs/s | 对缓冲池 LRU 列表中旧页的访问平均每秒次数,这些访问导致页被标记为年轻。更多信息请参见本表之后的说明。The per second average of accesses to old pages in the buffer pool LRU list that have resulted in making pages young. See the notes that follow this table for more information. |
| 非年轻页/秒non-youngs/s | 每秒平均访问缓冲池 LRU 列表中旧页面但未使页面变年轻的次数。更多信息请参见下表后的说明。The per second average of accesses to old pages in the buffer pool LRU list that have resulted in not making pages young. See the notes that follow this table for more information. |
| 读取的页面数Pages read | 从缓冲池中读取的页面总数。The total number of pages read from the buffer pool. |
| 创建的页面数Pages created | 在缓冲池中创建的页面总数。The total number of pages created within the buffer pool. |
| 写入的页面数Pages written | 从缓冲池写出的页面总数。The total number of pages written from the buffer pool. |
| 每秒读取次数reads/s | 缓冲池页面每秒读取的平均次数。The per second average number of buffer pool page reads per second. |
| 每秒创建次数creates/s | 缓冲池页面每秒创建的平均次数。The average number of buffer pool pages created per second. |
| 每秒写入次数writes/s | 缓冲池页面每秒写入的平均次数。The average number of buffer pool page writes per second. |
| 缓冲池命中率Buffer pool hit rate | 从缓冲池读取页面与从磁盘存储读取页面的缓冲池页面命中率。The buffer pool page hit rate for pages read from the buffer pool vs from disk storage. |
| 年轻化率young-making rate | 页面访问使页面变年轻的平均命中率。更多信息请参见下表后的说明。The average hit rate at which page accesses have resulted in making pages young. See the notes that follow this table for more information. |
| 未年轻化率not (young-making rate) | 页面访问未导致页面变为“年轻”的平均命中率。有关更多信息,请参阅此表后面的注释。The average hit rate at which page accesses have not resulted in making pages young. See the notes that follow this table for more information. |
| 预读取页面Pages read ahead | 每秒预读操作的平均值。The per second average of read ahead operations. |
| 未访问而被驱逐的页面Pages evicted without access | 从缓冲池中未被访问而被驱逐的页面的每秒平均值。The per second average of the pages evicted without being accessed from the buffer pool. |
| 随机预读Random read ahead | 随机预读操作的每秒平均值。The per second average of random read ahead operations. |
| LRU 长度LRU len | 缓冲池 LRU 列表的总页数。The total size in pages of the buffer pool LRU list. |
| unzip_LRU 长度unzip_LRU len | 缓冲池 unzip_LRU 列表的长度(以页为单位)。The length (in pages) of the buffer pool unzip_LRU list. |
| I/O 总和I/O sum | 缓冲池 LRU 列表访问的页面总数。The total number of buffer pool LRU list pages accessed. |
| 当前 I/OI/O cur | 当前时间间隔缓冲池 LRU 列表访问的页面总数。The total number of buffer pool LRU list pages accessed in the current interval. |
| I/O unzip 总和I/O unzip sum | 缓冲池 unzip_LRU 列表解压的页面总数。The total number of buffer pool unzip_LRU list pages decompressed. |
| I/O 解压 curI/O unzip cur | 当前间隔内缓冲池 unzip_LRU 列表页解压的总数。The total number of buffer pool unzip_LRU list pages decompressed in the current interval. |
注意:Notes:
youngs/s指标仅适用于旧页面。它基于页面访问次数。对于给定页面可以有多次访问,所有访问都会被计数。如果在没有大量扫描的情况下看到非常低的youngs/s值,请考虑减少延迟时间或增加用于旧子列表的缓冲池百分比。增加百分比会使旧子列表变大,从而使该子列表中的页面移动到尾部所需的时间更长,这会增加这些页面再次被访问并变年轻的可能性。参见 第 17.8.3.3 节,“使缓冲池具备扫描抵抗能力”。Theyoungs/smetric is applicable only to old pages. It is based on the number of page accesses. There can be multiple accesses for a given page, all of which are counted. If you see very lowyoungs/svalues when there are no large scans occurring, consider reducing the delay time or increasing the percentage of the buffer pool used for the old sublist. Increasing the percentage makes the old sublist larger so that it takes longer for pages in that sublist to move to the tail, which increases the likelihood that those pages are accessed again and made young. See Section 17.8.3.3, “Making the Buffer Pool Scan Resistant”.non-youngs/s指标仅适用于旧页。它基于页面访问次数。某个页面可能有多次访问,所有访问都会被计数。如果在执行大表扫描时没有看到更高的non-youngs/s值(以及更高的youngs/s值),请增加延迟值。请参见 第 17.8.3.3 节,“使缓冲池扫描具有抗性”。Thenon-youngs/smetric is applicable only to old pages. It is based on the number of page accesses. There can be multiple accesses for a given page, all of which are counted. If you do not see a highernon-youngs/svalue when performing large table scans (and a higheryoungs/svalue), increase the delay value. See Section 17.8.3.3, “Making the Buffer Pool Scan Resistant”.该
young-makingrate accounts for all buffer pool page accesses, not just accesses for pages in the old sublist. Theyoung-makingrate andnotrate do not normally add up to the overall buffer pool hit rate. Page hits in the old sublist cause pages to move to the new sublist, but page hits in the new sublist cause pages to move to the head of the list only if they are a certain distance from the head.Theyoung-makingrate accounts for all buffer pool page accesses, not just accesses for pages in the old sublist. Theyoung-makingrate andnotrate do not normally add up to the overall buffer pool hit rate. Page hits in the old sublist cause pages to move to the new sublist, but page hits in the new sublist cause pages to move to the head of the list only if they are a certain distance from the head.not (young-making rate)是平均命中率,当页访问未能使页面变年轻时,由于未满足innodb_old_blocks_time定义的延迟,或者由于新子列表中的页面命中未导致页面移动到头部。该比率计入所有缓冲池页面访问,而不仅仅是对旧子列表中页面的访问。not (young-making rate)is the average hit rate at which page accesses have not resulted in making pages young due to the delay defined byinnodb_old_blocks_timenot being met, or due to page hits in the new sublist that did not result in pages being moved to the head. This rate accounts for all buffer pool page accesses, not just accesses for pages in the old sublist.
缓冲池服务器状态变量和INNODB_BUFFER_POOL_STATS表提供了许多在InnoDB标准监视器输出中找到的相同缓冲池指标。有关更多信息,请参见示例 17.10,“查询 INNODB_BUFFER_POOL_STATS 表”。Buffer pool server status
variables and the
INNODB_BUFFER_POOL_STATS table
provide many of the same buffer pool metrics found in
InnoDB Standard Monitor output. For more
information, see
Example 17.10, “Querying the INNODB_BUFFER_POOL_STATS Table”.
