ITPub博客

首页 > 数据库 > > 14.6.3 InnoDB Buffer Pool 配置

14.6.3 InnoDB Buffer Pool 配置

作者:飘絮絮絮丶 时间:2020-05-12 10:03:07 0 删除 编辑

dev.mysql.com/doc/refma








14.6.3.1 InnoDB Buffer Pool


InnoDB维护一个称为缓冲池的存储区域,用于在内存中缓存数据和索引。 了解InnoDB缓冲池如何工作,并利用它来将频繁访问的数据保存在内存中,这是MySQL调优的一个重要方面。




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

  • 理想情况下,您可以将缓冲池的大小设置为尽可能大的值,从而为服务器上的其他进程留出足够的内存以在没有过多分页的情况下运行。 缓冲池越大,InnoDB就越像内存数据库,从磁盘读取数据一次,然后在后续读取期间从内存中访问数据。
  • 对于具有大内存大小的64位系统,您可以将缓冲池分成多个部分,以最大限度地减少并发操作之间的内存结构争用。
  • 尽管备份或报告等操作突然出现活动高峰,您仍可以将经常访问的数据保留在内存中。
  • 您可以控制InnoDB何时以及如何执行预读请求,以便预先将页面异步预取到缓冲池中,因为预计这些页面将很快需要使用。
  • 您可以控制何时发生脏页面的后台刷新,以及InnoDB是否根据工作负载动态调整刷新率。
  • 您可以微调InnoDB缓冲池刷新行为的各个方面,以提高性能。
  • 您可以配置InnoDB如何保留当前的缓冲池状态,以避免服务器重启后冗长的预热期。 您也可以在服务器运行时保存当前的缓冲池状态。





InnoDB Buffer Pool LRU 算法


InnoDB使用最近最少使用(LRU)算法的变体,将缓冲池作为列表来管理。 当需要将空间添加到池中时,InnoDB会清除最近最少使用的页面,并将新页面添加到列表的中间。 这种“中点插入策略”将列表视为两个子列表:

  • 头部是最近访问的“new”(或“young”)页面的子列表。
  • 尾部是最近访问过的“旧”页面的子列表。



该算法保留了新子列表中查询大量使用的页面。 旧的子列表包含较少使用的页面; 这些网页是驱逐的候选人。


LRU算法默认运行如下:

  • 3/8的缓冲池专用于旧的子列表。
  • 列表的中点是新子列表的尾部与旧子列表的头部相交的边界。
  • 当InnoDB将一个页面读入缓冲池时,它最初将它插入到中点(旧子列表的头部)。 可以读入页面,因为它是用户指定的操作(如SQL查询)所必需的,或者作为InnoDB自动执行的预读操作的一部分。
  • 在旧的子列表中访问一个页面会使其变得“young”,将其移动到缓冲池的头部(新子列表的头部)。 如果页面因为需要而被读入,则第一次访问立即发生并且页面变得年轻。 如果由于预读而导致页面被读入,则第一次访问不会立即发生(并且在页面被逐出之前可能根本不会发生)。
  • 随着数据库的运行,缓冲池中的页面不会通过移动到列表的尾部而被“访问”。 新的和旧的子列表中的页面随着其他页面的变化而变旧。 在中点插入页面时,旧子列表中的页面也会变老。 最终,一段长时间未使用的页面会到达旧的子列表的尾部并被驱逐。



默认情况下,查询读取的页面会立即移动到新的子列表中,这意味着它们会留在缓冲池中的时间更长。 表扫描(例如为mysqldump操作执行,或者不带WHERE子句的SELECT语句)可以将大量数据带入缓冲池并驱逐等量的旧数据,即使新数据再也不会使用。 同样,由预读后台线程加载,然后只访问一次的页面移动到新列表的头部。 这些情况可能会将经常使用的页面推送到旧的子列表中,他们可能会受到驱逐。


InnoDB Standard Monitor输出在缓冲池和内存部分包含与缓冲池LRU算法的操作相关的几个字段。




InnoDB缓冲池配置选项
几个影响InnoDB缓冲池的不同方面的配置选项。


指定缓冲池的大小。 如果缓冲池很小并且有足够的内存,那么通过减少查询访问InnoDB表所需的磁盘I / O量可以提高缓冲池的性能,从而提高性能。 innodb_buffer_pool_size选项是动态的,它允许您在不重新启动服务器的情况下配置缓冲池大小。

  • innodb_buffer_pool_chunk_size

定义InnoDB缓冲池调整大小操作的块大小


  • innodb_buffer_pool_instances

    将缓冲池划分为用户指定数量的单独区域,每个区域都有自己的LRU列表和相关数据结构,以减少并发内存读取和写入操作期间的争用。 只有将innodb_buffer_pool_size设置为1GB或更大的值时,此选项才会生效。 您指定的总大小被分配到所有缓冲池中。 为了获得最佳效率,请指定innodb_buffer_pool_instances和innodb_buffer_pool_size的组合,以便每个缓冲池实例至少为1 GB。 有关更多信息,请参见第14.6.3.3节“配置多个缓冲池实例”。


  • innodb_old_blocks_pct

    指定InnoDB用于旧块子列表的缓冲池的近似百分比。 值的范围是5到95.默认值是37(即池的3/8)。


  • innodb_old_blocks_time


指定插入到旧子列表中的页面在第一次访问后必须在毫秒(ms)内保留多长时间,然后才能移动到新子列表中。 如果值为0,则无论插入后何时发生访问,插入旧子列表的页面在第一次访问时都会立即移至新子列表。 如果该值大于0,则页面将保留在旧的子列表中,直到在第一次访问后至少几毫秒内发生访问。 例如,值为1000(默认值)会导致页面在第一次访问后停留在旧子表中1秒钟,然后才有资格移动到新子列表。


将innodb_old_blocks_time设置为大于0可防止一次性表扫描使用仅用于扫描的页面填充新的子列表。 读取的扫描页面中的行会连续快速访问多次,但该页面在此之后未被使用。 如果innodb_old_blocks_time设置为大于处理页面的时间的值,则该页面保留在“旧”子列表中,并且老化到列表的尾部以被快速驱逐。 这样,仅用于一次扫描的页面不会影响新子列表中大量使用的页面。



innodb_old_blocks_time可以在运行时设置,因此您可以在执行诸如表扫描和转储等操作时临时更改它:


SET GLOBAL innodb_old_blocks_time = 1000; ... perform queries that scan tables ...
SET GLOBAL innodb_old_blocks_time = 0;




如果您的意图是通过填充表格的内容来“缓冲”缓冲池,则此策略不适用。 例如,基准测试通常在服务器启动时执行表或索引扫描,因为在正常使用一段时间后,数据通常会在缓冲池中。 在这种情况下,请将innodb_old_blocks_time设置为0,至少在暖机阶段完成之前。

控制InnoDB用于预取页面到缓冲池中的线性预读的灵敏度。

  • innodb_random_read_ahead



使用随机预读技术将页面预取到缓冲池中。 随机预读是一项技术,可根据缓冲池中已有的页面快速预测何时需要页面,而不管这些页面的读取顺序如何。 innodb_random_read_ahead默认是禁用的。

指定是否根据工作负载动态调整缓冲池中刷新脏页的速率。 动态调整冲刷速率旨在避免I / O活动的爆发。 该设置默认启用。

指定是否从缓冲池中清除页面也会在相同范围内刷新其他脏页面。
默认是1 启用。




InnoDB保存之前计算的刷新状态快照的迭代次数,控制自适应刷新对更改工作负载的响应速度。
默认是 30



影响缓冲池刷新操作的算法和启发式的参数。 性能主要关注调整I / O密集型工作负载。 它为每个缓冲池实例指定了缓冲池LRU下多远,page_cleaner线程扫描寻找要刷新的脏页。
默认是1024




InnoDB会尝试从缓冲池中刷新数据,以便脏页面的百分比不超过此值。 指定范围从0到99的整数。默认值为75。




低水位的百分比表示启用来控制脏页预flush的比率。 默认值为0将完全禁用预冲洗行为。


默认是0



指定保存由innodb_buffer_pool_dump_at_shutdown或innodb_buffer_pool_dump_now生成的表空间ID和页面ID列表的文件的名称。


  • innodb_buffer_pool_dump_at_shutdown



指定在MySQL服务器关闭时是否记录缓冲池中缓存的页面,以缩短下次重新启动时的预热过程。
默认是启用



指定在MySQL服务器启动时,通过加载它在先前保存的相同页面,缓冲池自动预热。 通常与innodb_buffer_pool_dump_at_shutdown结合使用。


默认是on




立即记录在缓冲池中缓存的页面。


默认是OFF




立即通过加载一组数据页面来加热缓冲池,而无需等待服务器重新启动。 在基准测试期间将高速缓存恢复到已知状态,或者在运行查询报告或维护后,使MySQL服务器恢复正常工作负载,可能会很有用。 通常与innodb_buffer_pool_dump_now一起使用。



指定每个缓冲池读出和转储的最近使用页面的百分比。 范围是1到100。


默认是25




中断由innodb_buffer_pool_load_at_startup或innodb_buffer_pool_load_now触发的缓冲池内容恢复过程。
默认是OFF



14.6.3.2 配置InnoDB buffer pool 大小


您可以在服务器运行时将InnoDB缓冲池大小配置为离线(启动时)或联机。 本节中描述的行为适用于这两种方法。


当增加或减少innodb_buffer_pool_size时,操作以块为单位执行。 块大小由innodb_buffer_pool_chunk_size配置选项定义,默认值为128M。


缓冲池大小必须始终等于innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍数。 如果将innodb_buffer_pool_size配置为不等于或等于innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍数的值,则缓冲池大小会自动调整为等于或等于innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍数的值,该值不小于指定的缓冲池大小。


在以下示例中,innodb_buffer_pool_size设置为8G,innodb_buffer_pool_instances设置为16. innodb_buffer_pool_chunk_size为默认值128M。


8G是一个有效的innodb_buffer_pool_size值,因为8G是innodb_buffer_pool_instances = 16 * innodb_buffer_pool_chunk_size = 128M的倍数,即2G。



在本例中,innodb_buffer_pool_size设置为9G,innodb_buffer_pool_instances设置为16. innodb_buffer_pool_chunk_size为128M,这是默认值。 在这种情况下,9G不是innodb_buffer_pool_instances = 16 * innodb_buffer_pool_chunk_size = 128M的倍数,所以innodb_buffer_pool_size被调整为10G,这是innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的下一个不小于指定缓冲池大小的倍数。



配置 InnoBD buffer 池 Chunk 大小
innodb_buffer_pool_chunk_size可以以1MB(1048576字节)为单位增加或减少,但只能在启动时,命令行字符串或MySQL配置文件中修改。


命令行:


shell>
mysqld --innodb_buffer_pool_chunk_size=134217728


配置文件:


[mysqld]
innodb_buffer_pool_chunk_size=134217728




更改innodb_buffer_pool_chunk_size时,以下条件适用:

  • 如果在初始化缓冲池时,新的innodb_buffer_pool_chunk_size值* innodb_buffer_pool_instances大于当前的缓冲池大小,则innodb_buffer_pool_chunk_size将被截断为innodb_buffer_pool_size / innodb_buffer_pool_instances。



例如,如果初始化缓冲池的大小为2GB(2147483648字节),4个缓冲池实例和1GB的chunk大小(1073741824字节),则会将chunk大小截断为等于innodb_buffer_pool_size / innodb_buffer_pool_instances的值,如图所示 下面:


shell> mysqld --innodb_buffer_pool_size=2147483648 --innodb_buffer_pool_instances=4 --innodb_buffer_pool_chunk_size=1073741824;




mysql> SELECT @@innodb_buffer_pool_size;

+---------------------------+
| @@innodb_buffer_pool_size |
+---------------------------+
| 2147483648 |
+---------------------------+
mysql> SELECT @@innodb_buffer_pool_instances;

+--------------------------------+

| @@innodb_buffer_pool_instances |

+--------------------------------+
| 4 |
+--------------------------------+

# Chunk size was set to 1GB (1073741824 bytes) on startup but was # truncated to innodb_buffer_pool_size / innodb_buffer_pool_instances

mysql> SELECT @@innodb_buffer_pool_chunk_size;

+---------------------------------+

| @@innodb_buffer_pool_chunk_size |

+---------------------------------+
| 536870912 |
+---------------------------------+

  • 缓冲池大小必须始终等于innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的倍数。 如果您更改了innodb_buffer_pool_chunk_size,则innodb_buffer_pool_size将自动调整为等于或等于innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances的值不小于当前缓冲池大小的值。 调整发生在缓冲池初始化时。

    更改innodb_buffer_pool_chunk_size时应该小心,因为更改此值可以增加缓冲池的大小,如上例所示。 在更改innodb_buffer_pool_chunk_size之前,请计算对innodb_buffer_pool_size的影响,以确保生成的缓冲池大小可以接受。


    注意:
    为避免潜在的性能问题,chunk数量(innodb_buffer_pool_size / innodb_buffer_pool_chunk_size)不应超过1000。


    --也就是说默认128M的chunk大小,buffer poo最大不要超过125G。



    在线 配置 InnoDB buffer pool 大小


    innodb_buffer_pool_size配置选项可以使用SET语句动态设置,允许您在不重新启动服务器的情况下调整缓冲池的大小。 例如:


    mysql> SET GLOBAL innodb_buffer_pool_size=402653184;


    在调整缓冲池的大小之前,应该先完成通过InnoDB API执行的活动事务和操作。 启动调整大小操作时,直到所有活动事务完成后才会启动操作。 一旦调整大小操作正在进行中,需要访问缓冲池的新事务和操作必须等到调整大小操作完成。 规则的例外是,当缓冲池被碎片整理时,允许对缓冲池的并发访问,并且当缓冲池大小减小时撤回页面。 允许并发访问的一个缺点是它可能导致暂时缺少可用页面而页面正在被撤销。



    注意:
    如果在缓冲池调整大小操作开始后启动嵌套事务,则可能会失败。



    监控在线缓冲池调整进度


    Innodb_buffer_pool_resize_status报告缓冲池调整进度。 例如:


    mysql> SHOW STATUS WHERE Variable_name='InnoDB_buffer_pool_resize_status';
    +----------------------------------+----------------------------------+
    | Variable_name | Value |
    +----------------------------------+----------------------------------+
    | Innodb_buffer_pool_resize_status | Resizing also other hash tables.
    | +----------------------------------+----------------------------------+



    缓冲池调整大小进度也会记录在服务器错误日志中。


    在线缓冲池调整内部组件


    调整大小操作由后台线程执行。 当增加缓冲池的大小时,调整大小操作:

  • 以chunks的形式添加页面(块大小由innodb_buffer_pool_chunk_size定义)
  • Coverts哈希表,列表和指针在内存中使用新地址
  • 将新页面添加到空闲列表中


当这些操作正在进行时,其他线程将被阻止访问缓冲池。


减小缓冲池的大小时,调整大小操作:

  • 对缓冲池进行碎片整理并撤销(释放)页面
  • 以chunks形式移除页面(块大小由innodb_buffer_pool_chunk_size定义)
  • 转换哈希表,列表和指针以在内存中使用新地址


在这些操作中,只对缓冲池进行碎片整理和撤销页面,可以让其他线程同时访问缓冲池。



14.6.3.3 配置多个buffer pool 实例


对于缓冲池在数GB范围内的系统,通过在不同线程读取和写入缓存页面时减少争用,将缓冲池划分为不同的实例可以提高并发性。 此功能通常用于缓冲池大小在数GB范围内的系统。 使用innodb_buffer_pool_instances配置选项配置多个缓冲池实例,并且您还可以调整innodb_buffer_pool_size值。


当InnoDB缓冲池很大时,通过从内存中检索可以满足许多数据请求。 您可能会遇到来自尝试一次访问缓冲池的多个线程的瓶颈。 您可以启用多个缓冲池以最大限度地减少此争用。 存储在缓冲池中或从中读取的每个页面都使用散列函数随机分配给其中一个缓冲池。 每个缓冲池管理自己的空闲列表,刷新列表,LRU以及连接到缓冲池的所有其他数据结构,并受其自己的缓冲池互斥锁保护。


要启用多个缓冲池实例,请将innodb_buffer_pool_instances配置选项设置为大于1(默认值)最大为64(最大值)的值。 只有当您将innodb_buffer_pool_size设置为1GB或更大的大小时,此选项才会生效。 您指定的总大小被分配到所有缓冲池中。 为了获得最佳效率,请指定innodb_buffer_pool_instances和innodb_buffer_pool_size的组合,以便每个缓冲池实例至少为1GB。


14.6.3.4 使缓冲池 耐扫描


InnoDB并没有采用严格的LRU算法,而是采用了一种技术来最小化带入缓冲池的数据量,并且再也无法访问。 我们的目标是确保经常访问(“hot”)的页面保留在缓冲池中,即使预读和全表扫描带入可能或可能未被访问的新块。


新读取的块被插入到LRU列表的中间。 所有新读取的页面都插入到默认位置,距离LRU列表尾部3/8。 当页面首次在缓冲池中访问时,这些页面将移动到列表的最前面(最近使用的一端)。 因此,永远不会被访问的页面永远不会将它放到LRU列表的前面,并且比使用严格的LRU方法更快地“老化”。 这种安排将LRU列表分成两段,其中插入点下游的页面被认为是“旧”的,并且是LRU理想驱逐者。


有关InnoDB缓冲池内部工作原理和LRU算法细节的说明,请参见第14.6.3.1节“InnoDB缓冲池”。


您可以控制LRU列表中的插入点,并选择InnoDB是否对通过表或索引扫描进入缓冲池的块应用相同的优化。 配置参数innodb_old_blocks_pct控制LRU列表中“旧”块的百分比。 innodb_old_blocks_pct的默认值是37,对应于3/8的原始固定比率。 值的范围是5(缓冲池中的新页面非常快速地老化)到95(只有5%的缓冲池用于热页面,使得算法接近熟悉的LRU策略)。


保持缓冲池不被预读激活的优化可以避免由表或索引扫描造成的类似问题。 在这些扫描中,数据页面通常会连续快速访问几次,并且不会再次触摸。 配置参数innodb_old_blocks_time指定第一次访问页面之后的时间窗口(以毫秒为单位),在此期间,可以在不移动到LRU列表的前端(最近使用的末尾)的情况下访问它。 innodb_old_blocks_time的缺省值是1000.增加此值会使越来越多的块从缓冲池中快速老化。


innodb_old_blocks_pct和innodb_old_blocks_time都是动态的,全局的,可以在MySQL选项文件(my.cnf或my.ini)中指定,或者在运行时使用SET GLOBAL命令更改。 更改设置需要SUPER权限。


为了帮助您评估设置这些参数的效果,SHOW ENGINE INNODB STATUS命令报告缓冲池统计信息。


由于这些参数的影响因硬件配置,数据以及工作负载的细节而异,所以它们的测试总是基准,以验证在任何性能关键或生产环境中更改这些设置之前的有效性。


在混合工作负载中,大多数活动是OLTP类型,并且定期批量报告查询会导致大扫描,因此在批处理运行期间设置innodb_old_blocks_time的值可以帮助保持缓冲池中正常工作负载的工作集。




扫描不能完全放入缓冲池的大型表时,将innodb_old_blocks_pct设置为较小的值会使仅读取一次的数据占用大量缓冲池。 例如,设置innodb_old_blocks_pct = 5会限制只读取一次的数据到缓冲池的5%。


扫描适合内存的小表时,在缓冲池内移动页面所需的开销较小,因此您可以将innodb_old_blocks_pct保留为默认值,或者更高,例如innodb_old_blocks_pct = 50。


innodb_old_blocks_time参数的影响比innodb_old_blocks_pct参数更难预测,其相对较小,并且随工作负载而变化更大。 为了达到最佳值,如果调整innodb_old_blocks_pct的性能提升不足,则应执行自己的基准测试。




14.6.3.5配置InnoDB缓冲池预取(预读)


预读请求是一个I/O请求,用于预先异步预取缓冲池中的多个页面,预计这些页面很快就会被需要。 请求在一个范围内引入所有页面。 InnoDB使用两种预读算法来提高I/O性能:




线性预读是一项技术,可根据顺序访问的缓冲池中的页面快速预测可能需要的页面。 您可以使用配置参数innodb_read_ahead_threshold通过调整触发异步读取请求所需的顺序页面访问次数来控制InnoDB何时执行预读操作。 在添加此参数之前,InnoDB只会计算在读取当前范围的最后一页时,是否对下一个范围发出异步预取请求。




配置参数innodb_read_ahead_threshold控制InnoDB在检测连续页面访问模式方面的敏感程度。 如果从某个范围顺序读取的页数大于或等于innodb_read_ahead_threshold,则InnoDB会启动整个后续范围的异步预读操作。 innodb_read_ahead_threshold可以设置为0-64之间的任何值。 缺省值是56。值越高,访问模式检查越严格。 例如,如果将值设置为48,InnoDB只有在当前范围中的48页已被顺序访问时才会触发线性预读请求。 如果值为8,则即使连续访问范围内的最少8页,InnoDB也会触发异步预读。 您可以在MySQL配置文件中设置此参数的值,或者使用需要SUPER权限的SET GLOBAL命令动态更改它。


随机预读是一项技术,可根据缓冲池中已有的页面快速预测何时需要页面,而不管这些页面的读取顺序如何。 如果在缓冲池中找到来自相同范围的连续13个页面,则InnoDB会异步发出一个请求以预取剩余页面的范围。 要启用此功能,请将配置变量innodb_random_read_ahead设置为ON。


SHOW ENGINE INNODB STATUS命令显示统计信息,以帮助您评估预读算法的有效性。 统计数据包括以下全局状态变量的计数器信息:

  • Innodb_buffer_pool_read_ahead
  • Innodb_buffer_pool_read_ahead_evicted
  • Innodb_buffer_pool_read_ahead_rnd



这些信息在微调innodb_random_read_ahead设置时非常有用。



14.6.3.6 配置InnoDB 缓存池刷新


InnoDB在后台执行某些任务,包括从缓冲池中清除脏页(已更改但尚未写入数据库文件的那些页)。


当缓冲池中脏页的百分比达到innodb_max_dirty_pages_pct_lwm定义的低水位设置时,InnoDB开始刷新缓冲池页。 此选项旨在控制缓冲池中的脏页的比率,并理想地防止脏页的百分比达到innodb_max_dirty_pages_pct。 如果缓冲池中脏页的百分比超过innodb_max_dirty_pages_pct,InnoDB开始积极地刷新缓冲池页面。


InnoDB使用一种算法来根据重做日志生成的速度和当前刷新率来估计所需的刷新率。 其目的是通过确保缓冲区刷新活动与保持缓冲池“清洁”的需要相一致来平滑整体性能。 自动调整刷新速率有助于避免吞吐量突然下降,因为过多的缓冲池刷新限制了普通读写活动可用的I / O容量。


InnoDB使用启发式算法来避免这种情况,通过测量缓冲池中脏页的数量和生成重做的速率。 根据这些数字,InnoDB决定每秒钟从缓冲池刷新多少脏页。 这种自适应算法能够处理工作负载的突然变化。


内部基准测试表明,该算法不仅可以保持一段时间的吞吐量,还可以显着提高整体吞吐量。


由于自适应刷新可以显着影响工作负载的I/O模式,因此可以使用innodb_adaptive_flushing配置参数关闭此功能。 innodb_adaptive_flushing的默认值为ON,启用自适应刷新算法。 您可以在MySQL选项文件(my.cnf或my.ini)中设置此参数的值,或者使用需要SUPER特权的SET GLOBAL命令动态更改它。




14.6.3.7 微调InnoDB缓冲池刷新


配置选项innodb_flush_neighbors和innodb_lru_scan_depth可让您调整InnoDB缓冲池的刷新过程的各个方面。

  • innodb_flush_neighbors



指定是否从缓冲池中清除页面也会在相同范围内刷新其他脏页面。 当表格数据存储在传统的HDD存储设备上时,与在不同时间冲刷单独页面相比,在一个操作中冲刷相邻页面减少了I / O开销(主要用于磁盘搜索操作)。 对于存储在SSD上的表数据,寻道时间不是一个重要因素,您可以禁用此设置以分散写入操作。

为每个缓冲池实例指定缓冲池LRU列表多少,页面清理器线程扫描寻找要刷新的脏页面。 这是每秒执行一次的后台操作。


这些选项主要有助于编写密集型工作负载。 如果DML活动繁重,如果不够积极,刷新可能会落后,导致缓冲池中的内存使用过多; 或者如果这种机制过于激进,由于刷新导致的磁盘写入可能会使您的I / O容量饱和。 理想的设置取决于您的工作负载,数据访问模式和存储配置(例如,数据是存储在HDD还是SSD设备上)。


对于工作负载繁重或工作负载波动很大的系统,可以使用多个配置选项来微调InnoDB表的刷新行为:

  • innodb_adaptive_flushing_lwm
  • innodb_max_dirty_pages_pct_lwm
  • innodb_io_capacity_max
  • innodb_flushing_avg_loops



这些选项提供给innodb_adaptive_flushing选项使用的公式。




innodb_adaptive_flushing,innodb_io_capacity和innodb_max_dirty_pages_pct选项受以下选项的限制或扩展:

  • innodb_adaptive_flushing_lwm
  • innodb_io_capacity_max
  • innodb_max_dirty_pages_pct_lwm



InnoDB自适应冲洗机制并不适用于所有情况。 当重做日志存在填满危险时,它提供了最大的好处。 innodb_adaptive_flushing_lwm选项指定重做日志容量的“低水位”百分比; 当超过该阈值时,即使未由innodb_adaptive_flushing选项指定,InnoDB也会启用自适应刷新。



如果刷新活动远远落后,InnoDB可以比innodb_io_capacity指定的刷新更积极。 innodb_io_capacity_max表示在此类紧急情况下使用的I/O容量的上限,以便I/O中的峰值不会消耗服务器的性能。


InnoDB会尝试从缓冲池中清除数据,以使脏页面的百分比不超过innodb_max_dirty_pages_pct的值。 innodb_max_dirty_pages_pct的默认值是75。



注意:
innodb_max_dirty_pages_pct设置为冲洗活动建立目标。 它不会影响冲洗的速度。


innodb_max_dirty_pages_pct_lwm选项指定一个“低水位”值,该值表示启用预先刷新以控制脏页比率并理想地防止脏页百分比达到innodb_max_dirty_pages_pct的脏页的百分比。 innodb_max_dirty_pages_pct_lwm = 0的值会禁用“预冲洗”行为。


上面提到的大多数选项最适用于长时间运行写入繁重工作负载的服务器,并且几乎没有减少加载时间以赶上等待写入磁盘的更改。


innodb_flushing_avg_loops定义了InnoDB保留之前计算的刷新状态快照的迭代次数,它控制自适应刷新响应前景负载变化的速度。为innodb_flushing_avg_loops设置一个较高的值意味着InnoDB保持之前计算的快照时间更长,所以自适应刷新响应速度更慢。较高的值也会减少前台和后台工作之间的正反馈,但设置较高值时,确保InnoDB重做日志利用率未达到75%(异步刷新开始的硬编码限制)并且innodb_max_dirty_pages_pct设置保持不变将脏页面数量设置为适合工作负载的级别。


具有一致工作负载,大型innodb_log_file_size和未达到75%重做日志空间利用率的小型峰值的系统应该使用高innodb_flushing_avg_loops值来尽可能保持平滑。对于极端负载峰值或日志文件不足以提供大量空间的系统,请考虑使用较小的innodb_flushing_avg_loops值。较小的值允许冲洗以紧密跟踪负载,并有助于避免达到75%的重做日志空间利用率。




14.6.3.8 保存和恢复缓冲池状态


为了减少重新启动服务器后的预热时间,InnoDB会在服务器关闭时为每个缓冲池保存一定比例的最近使用的页面,并在服务器启动时恢复这些页面。 最近使用的页面的百分比由innodb_buffer_pool_dump_pct配置选项定义。




在重新启动繁忙的服务器之后,通常会有一个预热期,吞吐量稳步增加,因为缓冲池中的磁盘页被带回到内存中(因为查询,更新了相同的数据)。 在启动时恢复缓冲池的功能通过在重新启动之前重新加载缓冲池中的磁盘页而缩短了预热期,而不是等待DML操作访问相应的行。 此外,I/O请求可以大批量执行,从而使整体I / O更快。 页面加载发生在后台,并且不会延迟数据库启动。




除了在关闭时保存缓冲池状态并在启动时恢复缓冲池状态外,您还可以在服务器运行时随时保存和恢复缓冲池状态。 例如,您可以在稳定的工作负载下达到稳定的吞吐量后保存缓冲池的状态。 运行将数据页面带入缓冲池的报表或维护作业(仅针对这些操作请求)或运行其他非典型工作负载后,还可以恢复以前的缓冲池状态。


尽管一个缓冲池的大小可能是数GB,但InnoDB保存到磁盘的缓冲池数据相比之下却很小。 只有定位适当页面所需的表空间ID和页面ID才会保存到磁盘。 此信息来自INNODB_BUFFER_PAGE_LRU INFORMATION_SCHEMA表。 默认情况下,表空间ID和页面ID数据保存在名为ib_buffer_pool的文件中,该文件保存在InnoDB数据目录中。 文件名和位置可以使用innodb_buffer_pool_filename配置参数进行修改。


由于数据与常规数据库操作一样,缓存在缓冲池中并且超出缓冲池,因此,如果最近更新了磁盘页面,或者如果DML操作涉及尚未加载的数据,则没有问题。 加载机制跳过不存在的请求页面。


底层机制涉及调度执行转储和加载操作的后台线程。


压缩表中的磁盘页面以压缩格式加载到缓冲池中。 在DML操作期间访问页面内容时,页面像往常一样解压缩。 由于解压缩页面是CPU密集型进程,因此在连接线程中执行并行操作比执行缓冲池恢复操作的单个线程的效率更高。


以下主题描述了与保存和恢复缓冲池状态相关的操作:


为buffer pool 也没配置dumo 百分比


在从缓冲池中转储页面之前,可以通过设置innodb_buffer_pool_dump_pct选项来配置要转储的最近使用的缓冲池页面的百分比。 如果您计划在服务器运行时转储缓冲池页面,则可以动态配置该选项:


SET GLOBAL innodb_buffer_pool_dump_pct=40;


如果您计划在服务器关闭时转储缓冲池页面,请在您的配置文件中设置innodb_buffer_pool_dump_pct。


[mysqld]
innodb_buffer_pool_dump_pct=40


在MYSQL5.7中当innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup被默认启用时,innodb_buffer_pool_dump_pct默认值从100(转储所有页面)变为25(转储最近使用页面的25%)。




在关机时保存缓冲池状态并在启动时恢复


要在关闭服务器时保存缓冲池的状态,请在关闭服务器之前发出以下语句:


SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;

innodb_buffer_pool_dump_at_shutdown默认启用。


要在服务器启动时恢复缓冲池状态,请在启动服务器时指定--innodb_buffer_pool_load_at_startup选项:


mysqld --innodb_buffer_pool_load_at_startup=ON;

innodb_buffer_pool_load_at_startup默认启用。




在线保存和重建buffer pool状态




要在MySQL服务器运行时保存缓冲池的状态,请发出以下语句:


SET GLOBAL innodb_buffer_pool_dump_now=ON;


要在MySQL运行时恢复缓冲池状态,请发出以下语句:


SET GLOBAL innodb_buffer_pool_load_now=ON;




显示 buffer pool dump 过程
要将缓冲池状态保存到磁盘时显示进度,请发出以下语句:


SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status';


如果操作尚未开始,则返回“ not started”。 如果操作完成,则打印完成时间(例如, Finished at 110505 12:18:02)。 如果操作正在进行中,则提供状态信息(例如, Dumping buffer pool 5/7, page 237/2873)。




显示 buffer pool 加载过程
要在加载缓冲池时显示进度,请发出以下语句:


SHOW STATUS LIKE 'Innodb_buffer_pool_load_status';


如果操作尚未开始,则返回“ not started”。 如果操作完成,则打印完成时间(例如, Finished at 110505 12:23:24)。 如果操作正在进行中,则提供状态信息(例如, Loaded 123/22301 pages)。



中断 buffer pool 加载操作


要中止缓冲池加载操作,请发出以下语句:


SET GLOBAL innodb_buffer_pool_load_abort=ON;




使用性能方案监视缓冲池负载进度


您可以使用性能方案监视缓冲池负载进度。


以下示例演示如何启用stage/innodb/buffer pool加载阶段事件工具和相关的使用者表以监视缓冲池加载进度。


有关此示例中使用的缓冲池转储和加载过程的信息,请参见第14.6.3.8节“保存和恢复缓冲池状态”。 有关Performance Schema阶段事件工具和相关使用者的信息,请参见第25.11.5节“性能模式阶段事件表”。


  • 启用stage/innodb/buffer pool加载工具:

    mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'stage/innodb/buffer%';


  • 启用舞台事件使用者表格,其中包括events_stages_current,events_stages_history和events_stages_history_long。



mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%';

  • 通过启用innodb_buffer_pool_dump_now来转储当前的缓冲池状态。

mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;

  • 检查缓冲池转储状态以确保操作已完成。



mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status'\G *************************** 1. row ***************************
Variable_name: Innodb_buffer_pool_dump_status
Value: Buffer pool(s) dump completed at 150202 16:38:58

  • 通过启用innodb_buffer_pool_load_now加载缓冲池:

mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;

通过查询性能模式events_stages_current表来检查缓冲池加载操作的当前状态。 WORK_COMPLETED列显示加载的缓冲池页面的数量。 WORK_ESTIMATED列以页面形式提供剩余工作的估计值。


mysql>SELECTEVENT_NAME,WORK_COMPLETED,WORK_ESTIMATEDFROMperformance_schema.events_stages_current;



如果缓冲池加载操作已完成,则events_stages_current表将返回一个空集。 在这种情况下,您可以检查events_stages_history表以查看已完成事件的数据。 例如:


mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_history;


注意:
在启动时使用innodb_buffer_pool_load_at_startup加载缓冲池时,您还可以使用性能模式监视缓冲池加载进度。 在这种情况下,启动时必须启用stage/innodb/buffer pool load instrument和相关的用户。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3159801/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-09

  • 博文量
    2646
  • 访问量
    42320