Buffer Pool

83 阅读7分钟

一、什么是 Buffer Pool

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

解释:

是内存中的一块区域,InnoDB 用来缓存它访问过的数据和索引。Buffer Pool 允许经常使用的数据直接从内存访问,加快了处理速度。在专门的服务器中,约 80% 的内存被用作缓冲池

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

解释:

为了大量读取操作的效率,缓冲池被划分为可能容纳多行的页。为了缓存管理的效率,缓冲池被实现为页面的链接列表;数据很少使用的将从缓存中移除(使用变种的 LRU 算法)

Knowing how to take advantage of the buffer pool to keep frequently accessed data in memory is an important aspect of MySQL tuning

解释:

如何发挥缓冲池的有利条件是保持经常访问的数据在内存中

二、变种的 LRU 算法(重点)

当一个页将要加入到缓冲池中,最近最少使用的页将被驱逐,新的页将加入到列表的 midpoint 位置。midpoint 插入策略把列表分为 2 个部分

  • At the head, a sublist of new (“young”) pages that were accessed recently

    New pages:经常访问的页

  • At the tail, a sublist of old pages that were accessed less recently

    old pages:很少访问的页

如下图所示:

该算法保持经常访问的页在 new sublist 中;old sublist 包含很少访问的页,这些页将考虑被驱逐

默认情况下,算法像如下方式运行:

  • the buffer pool 的 3/8 处被对待为 old sublist

  • 列表的 midpoint 位置是分界线

  • 当 InnoDB 读取一个页到缓冲池中时,页的插入位置是 old sublist 的 head 部分

  • 访问 old sublist 中的页会使它变『young』,随后把它移动到 new sublist 的 head 部分

  • 随着数据库的运行,缓冲池中未被访问的页通过向列表的尾部移动而"老化",无论是 new sublist 还是 old sublist 都随着其它页变新而"老化",最终页面保留未被访问直到 old sublist 的尾部随后被驱逐

三、Buffer Pool 的优化

默认的,查询读取到的页是立刻被加入到 new sublist 的头部,意味着它们在缓冲池中长时间停留。但是有以下情况不一样

  • 表扫描、不带 where 条件的 select 语句加载的页

    特点:大量的页被加载到缓冲池中,尽管它们不会再被使用

  • 来自后台线程的"预读"加载的页

    特点:不会再被使用

使 Buffer Pool 不受表扫描影响

对比严格的 LRU 算法,InnoDB 使用一种技术来最大限度地减少进入[缓冲池]的数据量,再也没有访问过的。目标是使经常访问的页面保留在缓冲池中,即使是"提前读取"或者"全表扫描"引入可能访问或不可能访问的新块

新读取的块被插入到列表的 middle 位置,通常是距离LRU列表尾部 3/8 处。第一次在缓冲池中访问页面时,页面会移动到列表的前面(最近使用的末尾)。因此,从未被访问过的页面永远不会出现在LRU列表的前部,并且比使用严格的LRU方法更快地“老化”

  • innodb_old_blocks_pct

    作用:指定合适的百分比,InnoDB Buffer Pool 被用作 old block sublist 的百分比,默认值是 37

  • innodb_old_blocks_time

    作用:

    1、非 0 值保护反对填充 Buffer Pool,用短暂时期的停留的数据,例如在表扫描期间

    2、增加这个值提供更多的保护反对表扫描的数据填充到 Buffer Pool 中

    3、默认值是 1000,即 1 秒

    **白话文:**就是针对表扫描加入到 old sublist 头部的页需要在 old sublist 中停留一段时间,停留一段时间后被重新访问才会加入到 new sublist 中,否则就在 old sublist 中等待驱逐

默认的,通过以上 2 个参数,可以解决预读或全表扫描带来的临时 pages 被缓存在缓冲池中的问题

配置缓冲池的预读

innodb_read_ahead_threshold 参数用来控制 InnoDB 连续页访问的敏感度。如果一个 extent 中连续读取的页大于等于该值的配置,则会开启异步 read-ahead 下一个完整的 extent 的读取。也就是说该值如果配置的越小就越敏感就越容易导致 『预读』下一个 extent

四、Buffer Pool Configuration

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

五、监控缓冲池

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]

以下表格提供了部分指标的说明:

NameDescription
Total memory allocatedThe total memory allocated for the buffer pool in bytes.
Dictionary memory allocatedThe total memory allocated for the InnoDB data dictionary in bytes.
Buffer pool sizeThe total size in pages allocated to the buffer pool.
Free buffersThe total size in pages of the buffer pool free list.
Database pagesThe total size in pages of the buffer pool LRU list.
Old database pagesThe total size in pages of the buffer pool old LRU sublist.
Modified db pagesThe current number of pages modified in the buffer pool.
Pages made youngThe total number of pages made young in the buffer pool LRU list (moved to the head of sublist of “new” pages).
Pages made not youngThe 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).
Pages readThe total number of pages read from the buffer pool.
Pages createdThe total number of pages created within the buffer pool.
Pages writtenThe total number of pages written from the buffer pool.
Buffer pool hit rateThe buffer pool page hit rate for pages read from the buffer pool vs from disk storage.
Pages evicted without accessThe per second average of the pages evicted without being accessed from the buffer pool.
LRU lenThe total size in pages of the buffer pool LRU list.
unzip_LRU lenThe length (in pages) of the buffer pool unzip_LRU list.

传送门: 保姆式Spring5源码解析

欢迎与作者一起交流技术和工作生活

联系作者