InnoDB缓冲池
缓冲池是主内存中的一个区域,在InnoDB
访问表和索引数据时会在其中进行高速缓存。缓冲池允许直接从内存中处理经常使用的数据,从而加快了处理速度。在专用服务器上,通常将多达80%的物理内存分配给缓冲池。
为了提高大容量读取操作的效率,缓冲池分为多个页面,这些页面可以潜在地容纳多行。为了提高缓存管理的效率,缓冲池被实现为页面的链接列表。使用LRU算法的变体将很少使用的数据从缓存中老化掉。
知道如何利用缓冲池将经常访问的数据保留在内存中是MySQL调优的重要方面。
缓冲池LRU算法
使用最近最少使用(LRU)算法的变体,将缓冲池作为列表进行管理。当需要空间以将新页面添加到缓冲池时,将驱逐最近使用最少的页面,并将新页面添加到列表的中间。此中点插入策略将列表视为两个子列表:
- 最前面是最近访问过的新页面(“年轻”)的子列表
- 在末尾,是最近访问的旧页面的子列表
图15.2缓冲池列表
该算法将大量页面保留在新的子列表中。旧的子列表包含较少使用的页面;这些页面是驱逐的候选对象。
默认情况下,该算法的运行方式如下:
- 3/8的缓冲池专用于旧的子列表。
- 列表的中点是新子列表的尾部与旧子列表的头相交的边界。
- 当
InnoDB
将页面读入缓冲池时,它首先将其插入中点(旧子列表的头部)。可以读取页面,因为它是用户启动的操作(例如SQL查询)所必需的,或作为的自动执行的预读操作的一部分InnoDB
。 - 访问旧子列表中的页面使其变为“年轻”,将其移至新子列表的开头。如果由于用户启动的操作而需要读取页面,则立即进行首次访问,并使页面年轻。如果由于预读操作而读取了该页面,则第一次访问不会立即发生,并且在退出该页面之前可能根本不会发生。
- 随着数据库的运行,通过移至列表的尾部,缓冲池中未被访问的页面将“老化”。新的和旧的子列表中的页面都会随着其他页面的更新而老化。随着将页面插入中点,旧子列表中的页面也会老化。最终,未使用的页面到达旧子列表的尾部并被逐出。
默认情况下,查询读取的页面会立即移入新的子列表,这意味着它们在缓冲池中的停留时间更长。例如,针对mysqldump操作或SELECT
不带WHERE
子句的语句执行的表扫描可以将大量数据带入缓冲池,并驱逐同等数量的旧数据,即使不再使用新数据也是如此。同样,由预读后台线程加载且仅访问一次的页面将移至新列表的开头。这些情况可能会将常用页面推到旧的子列表,在此它们会被逐出。有关优化此行为的信息,请参见“使缓冲池扫描具有抵抗力”和“配置InnoDB缓冲池预取(预读)”。
InnoDB
标准监视器输出在BUFFER POOL AND MEMORY
有关缓冲池LRU算法操作的部分中包含几个字段。有关详细信息,请参阅使用InnoDB Standard Monitor监视缓冲池。
缓冲池配置
您可以配置缓冲池的各个方面以提高性能。
- 理想情况下,您可以将缓冲池的大小设置为与实际一样大的值,从而为服务器上的其他进程留出足够的内存以运行而不会进行过多的分页。缓冲池越大,就越
InnoDB
像内存数据库一样,从磁盘读取一次数据,然后在后续读取期间从内存访问数据。请参见“配置InnoDB缓冲池大小”。 - 在具有足够内存的64位系统上,可以将缓冲池分成多个部分,以最大程度地减少并发操作之间的内存结构争用。有关详细信息,请参见“配置多个缓冲池实例”。
- 您可以将频繁访问的数据保留在内存中,而不必考虑操作突然导致的活动高峰,这些操作会将大量不经常访问的数据带入缓冲池。有关详细信息,请参见“使缓冲池扫描具有抵抗力”。
- 您可以控制何时以及如何执行预读请求,以异步方式将页面预取到缓冲池中,从而预期很快将需要这些页面。有关详细信息,请参见“配置InnoDB缓冲池预取(预读)”。
- 您可以控制何时进行后台冲洗,以及是否根据工作负荷动态调整冲洗速率。有关详细信息,请参见“配置缓冲池刷新”。
- 您可以配置如何
InnoDB
保留当前缓冲池状态,以免在服务器重新启动后进行冗长的预热。有关详细信息,请参见“保存和恢复缓冲池状态”。
使用InnoDB标准监视器监视缓冲池
InnoDB
可以使用访问的标准监视器输出,SHOW ENGINE INNODB STATUS
提供有关缓冲池操作的度量。缓冲池度量标准位于BUFFER POOL AND MEMORY
“InnoDB
标准监视器”输出中的部分,其外观类似于以下内容:
---------------------- BUFFER POOL ANDMEMORY ---------------------- Total largememory allocated 2198863872 Dictionarymemory allocated 776332 Buffer pool size 131072 Free buffers 124908Database pages 5720Old database pages 2071 Modified db pages 910 Pendingreads 0 Pending writes: LRU 0,flush list 0, singlepage 0 Pages made young 4, not young 0 0.10 youngs/s, 0.00 non-youngs/s Pagesread 197, created 5523, written 5060 0.00reads /s, 190.89 creates/s, 244.94 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pagesread ahead 0.00/s, evictedwithout 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
上次打印标准监视器输出以来经过的时间。
InnoDB缓冲池指标
名称 | 描述 |
---|---|
分配的总内存 | 为缓冲池分配的总内存(以字节为单位)。 |
分配的字典内存 | 为InnoDB 数据字典分配的总内存,以字节为单位。 |
缓冲池大小 | 分配给缓冲池的页面总大小。 |
可用缓冲区 | 缓冲池可用列表的页面总大小。 |
数据库页面 | 缓冲池LRU列表的页面总大小。 |
旧数据库页面 | 缓冲池旧LRU子列表的页面总大小。 |
修改的数据库页面 | 缓冲池中当前修改的页面数。 |
待读 | 等待读入缓冲池的缓冲池页面数。 |
待写LRU | 从LRU列表的底部开始写入的缓冲池中的旧脏页数。 |
等待写入刷新列表 | 检查点期间要刷新的缓冲池页面数。 |
待写单页 | 缓冲池中暂挂的独立页面写入数。 |
使页面年轻化 | 缓冲池LRU列表中变年轻的页面总数(已移至“ new ”页面的子列表的开头)。 |
页面不年轻 | 缓冲池LRU列表中没有年轻的页面总数(保留在“ old ”子列表中但没有年轻的页面)。 |
青少年 | 每秒访问缓冲池LRU列表中的旧页面的平均值,这导致页面变得年轻。有关更多信息,请参见此表后面的注释。 |
非年轻 | 每秒平均访问缓冲池LRU列表中的旧页面导致的页面不年轻。有关更多信息,请参见此表后面的注释。 |
阅读页面 | 从缓冲池读取的页面总数。 |
创建页面 | 在缓冲池中创建的页面总数。 |
写的页面 | 从缓冲池写入的页面总数。 |
读/秒 | 每秒平均缓冲池页面读取数。 |
创建/秒 | 每秒创建的每秒平均缓冲池页面数。 |
写/秒 | 每秒平均缓冲池页面写入数。 |
缓冲池命中率 | 从缓冲池内存与磁盘存储读取的页面的缓冲池页面命中率。 |
年青率 | 页面访问的平均命中率使页面更年轻。有关更多信息,请参见此表后面的注释。 |
不(成年率) | 页面访问未使页面变年轻的平均命中率。有关更多信息,请参见此表后面的注释。 |
预读页面 | 预读操作的每秒平均数。 |
被逐出的页面无法访问 | 每秒从缓冲池访问而未访问的页面的平均值。 |
随机阅读 | 随机预读操作的每秒平均数。 |
伦 | 缓冲池LRU列表的页面总大小。 |
unzip_LRU len | 缓冲池unzip_LRU列表的页面总大小。 |
I / O总和 | 最近50秒内访问的缓冲池LRU列表页的总数。 |
I / O电流 | 已访问的缓冲池LRU列表页面的总数。 |
I / O解压缩总和 | 已访问的缓冲池unzip_LRU列表页面的总数。 |
I / O解压缩 | 已访问的缓冲池unzip_LRU列表页面的总数。 |
名称 | 描述 |
---|
注意事项:
- 该
youngs/s
指标仅适用于旧页面。它基于对页面的访问次数而不是页面数。可以对给定页面进行多次访问,所有访问都计入在内。如果youngs/s
在不进行大扫描时看到非常低的值,则可能需要减少延迟时间或增加用于旧子列表的缓冲池的百分比。增加百分比会使旧的子列表变大,因此该子列表中的页面需要更长的时间才能移到尾部,这增加了再次访问这些页面并使它们变年轻的可能性。 - 该
non-youngs/s
指标仅适用于旧页面。它基于对页面的访问次数而不是页面数。可以对给定页面进行多次访问,所有访问都计入在内。如果non-youngs/s
在执行大表扫描时看不到较高的值(较高的youngs/s
值),请增加延迟值。 - 该
young-making
比率说明了对所有缓冲池页面的访问,而不仅仅是访问了旧子列表中的页面。该young-making
速率和not
速率通常不会加总到整个缓冲池的命中率。旧的子列表中的页面命中会导致页面移至新的子列表,但是新的子列表中的页面命中只会导致页面与列表的头部保持一定距离时才移至列表的头部。 not(young-making rate)
是由于innodb_old_blocks_time
未满足所定义的延迟,或者由于新子列表中的页面命中并未导致页面移动到头部而导致页面访问未使页面年轻化的平均命中率。此速率说明了对所有缓冲池页面的访问,而不仅仅是访问旧子列表中的页面。
缓冲池服务器状态变量和INNODB_BUFFER_POOL_STATS
表提供了许多与InnoDB
标准监视器输出中相同的缓冲池度量标准。有关更多信息,请参见示例15.10,“查询INNODB_BUFFER_POOL_STATS表”。