14.5.2 更改缓冲区

更改缓冲区是一种特殊的数据结构,当这些页面不在buffer pool中时,该缓存可缓存对secondary index页的更改。可能由INSERTUPDATEDELETE操作(DML)导致的缓冲更改将在以后通过其他读取操作将页面加载到缓冲池中时合并。

图 14.3 更改缓冲区

内容在周围的 Literals 中描述。

clustered indexes不同,二级索引通常是不唯一的,并且二级索引中的插入以相对随机的 Sequences 发生。同样,删除和更新可能会影响索引树中不相邻的二级索引页。当稍后通过其他操作将受影响的页读入缓冲池时,合并缓存的更改将避免从磁盘将辅助索引页读入缓冲池所需的大量随机访问 I/O。

在系统大部分处于空闲状态或缓慢关闭期间运行的清除操作会定期将更新的索引页写入磁盘。与将每个值立即写入磁盘相比,清除操作可以更有效地为一系列索引值写入磁盘块。

当有许多受影响的行和许多辅助索引要更新时,更改缓冲区合并可能需要几个小时。在此期间,磁盘 I/O 会增加,这可能会导致磁盘绑定查询的速度大大降低。提交事务之后,甚至在服务器关闭并重新启动之后,更改缓冲区合并也可能 continue 发生(有关更多信息,请参见第 14.22.2 节“强制 InnoDB 恢复”)。

在内存中,更改缓冲区占用了缓冲池的一部分。在磁盘上,更改缓冲区是系统 table 空间的一部分,当数据库服务器关闭时,索引更改将存储在其中。

更改缓冲区中缓存的数据类型由innodb_change_buffering变量控制。有关更多信息,请参见配置变更缓冲。您还可以配置最大更改缓冲区大小。有关更多信息,请参见配置更改缓冲区最大大小

如果索引包含降序索引列或主键包含降序索引列,则辅助索引不支持更改缓冲。

有关有关更改缓冲区的常见问题的解答,请参见第 A.16 节“ MySQL 5.7 FAQ:InnoDB 更改缓冲区”

配置更改缓冲

当对 table 执行INSERTUPDATEDELETE操作时,索引列的值(尤其是辅助键的值)通常处于未排序的 Sequences,需要大量的 I/O 才能使辅助索引保持最新状态。当相关的page不在buffer pool中时,change buffer缓存对辅助索引条目的更改,从而通过不立即从磁盘读取页面来避免昂贵的 I/O 操作。当页面加载到缓冲池中时,缓冲的更改将合并,更新的页面随后将刷新到磁盘。 InnoDB主线程在服务器接近空闲时和slow shutdown期间合并缓冲的更改。

由于更改缓冲区功能可以减少磁盘读写操作,因此它对于受 I/O 约束的工作负载(例如,具有大量 DML 操作的应用程序,例如批量插入)最有价值。

但是,更改缓冲区占用了缓冲池的一部分,从而减少了可用于缓存数据页的内存。如果工作集几乎适合缓冲池,或者您的 table 具有相对较少的二级索引,则禁用更改缓冲可能很有用。如果工作数据集完全适合缓冲池,则更改缓冲不会带来额外的开销,因为它仅适用于不在缓冲池中的页面。

您可以使用innodb_change_buffering配置参数来控制InnoDB执行更改缓冲的程度。您可以为插入,删除操作(最初将索引记录标记为删除)和清除操作(物理删除索引记录)启用或禁用缓冲。更新操作是插入和删除的组合。 innodb_change_buffering的默认值为all

允许的innodb_change_buffering值包括:

  • all

默认值:缓冲区插入,删除标记操作和清除。

  • none

不要缓冲任何操作。

  • inserts

缓冲区插入操作。

  • deletes

缓冲区删除标记操作。

  • changes

缓冲插入和删除标记操作。

  • purges

缓冲在后台发生的物理删除操作。

您可以在 MySQL 选项文件(my.cnfmy.ini)中设置innodb_change_buffering参数,或使用SET GLOBAL语句动态更改它,该语句需要足够的权限来设置全局系统变量。参见第 5.1.8.1 节“系统变量特权”。更改设置会影响新操作的缓冲;现有缓冲条目的合并不受影响。

配置更改缓冲区最大大小

innodb_change_buffer_max_size变量允许将更改缓冲区的最大大小配置为缓冲池总大小的百分比。默认情况下,innodb_change_buffer_max_size设置为 25.最大设置为 50.

考虑在具有大量插入,更新和删除活动的 MySQL 服务器上增加innodb_change_buffer_max_size,其中更改缓冲区合并不能与新的更改缓冲区条目保持同步,从而导致更改缓冲区达到其最大大小限制。

考虑在 MySQL 服务器上使用用于报告的静态数据减少innodb_change_buffer_max_size,或者如果更改缓冲区占用了与缓冲池共享的太多内存空间,从而导致页面比期望的更快地超出缓冲池。

使用代 table 性的工作负载测试不同的设置,以确定最佳配置。 innodb_change_buffer_max_size设置是动态的,它允许修改设置而无需重新启动服务器。

监视更改缓冲区

以下选项可用于更改缓冲区监视:

  • InnoDB Standard Monitor 输出包括更改缓冲区状态信息。要查看监视器数据,请发出SHOW ENGINE INNODB STATUS语句。
mysql> SHOW ENGINE INNODB STATUS\G

更改缓冲区状态信息位于INSERT BUFFER AND ADAPTIVE HASH INDEX标题下,并显示类似以下内容:

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 4425293, used cells 32, node heap has 1 buffer(s)
13577.57 hash searches/s, 202.47 non-hash searches/s

有关更多信息,请参见第 14.18.3 节“ InnoDB 标准监视器和锁定监视器输出”

  • INFORMATION_SCHEMA.INNODB_METRICStable 提供了在InnoDB Standard Monitor 输出中找到的大多数数据点以及其他数据点。要查看更改缓冲区度量标准以及每个度量标准的描述,请发出以下查询:
mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%ibuf%'\G

有关INNODB_METRICStable 使用情况的信息,请参见第 14.16.6 节“ InnoDB INFORMATION_SCHEMAMetricstable”

  • INFORMATION_SCHEMA.INNODB_BUFFER_PAGEtable 提供有关缓冲池中每个页面的元数据,包括更改缓冲区索引和更改缓冲区位图页面。更改缓冲区页由PAGE_TYPE标识。 IBUF_INDEX是更改缓冲区索引页的页面类型,IBUF_BITMAP是更改缓冲区位图页的页面类型。

Warning

查询INNODB_BUFFER_PAGEtable 可能会带来很大的性能开销。为避免影响性能,请重现要在测试实例上调查的问题,然后在测试实例上运行查询。

例如,您可以查询INNODB_BUFFER_PAGEtable 来确定IBUF_INDEXIBUF_BITMAP页的总数大约占缓冲池页面总数的百分比。

mysql> SELECT (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
       WHERE PAGE_TYPE LIKE 'IBUF%') AS change_buffer_pages,
       (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE) AS total_pages,
       (SELECT ((change_buffer_pages/total_pages)*100))
       AS change_buffer_page_percentage;
+---------------------+-------------+-------------------------------+
| change_buffer_pages | total_pages | change_buffer_page_percentage |
+---------------------+-------------+-------------------------------+
|                  25 |        8192 |                        0.3052 |
+---------------------+-------------+-------------------------------+

有关INNODB_BUFFER_PAGEtable 提供的其他数据的信息,请参见第 24.32.1 节,“ INFORMATION_SCHEMA INNODB_BUFFER_PAGEtable”。有关相关用法信息,请参见第 14.16.5 节“ InnoDB INFORMATION_SCHEMA 缓冲池 table”

  • Performance Schema提供更改缓冲区互斥锁 await 检测,以进行高级性能监视。要查看更改缓冲区检测,请发出以下查询:
mysql> SELECT * FROM performance_schema.setup_instruments
       WHERE NAME LIKE '%wait/synch/mutex/innodb/ibuf%';
+-------------------------------------------------------+---------+-------+
| NAME                                                  | ENABLED | TIMED |
+-------------------------------------------------------+---------+-------+
| wait/synch/mutex/innodb/ibuf_bitmap_mutex             | YES     | YES   |
| wait/synch/mutex/innodb/ibuf_mutex                    | YES     | YES   |
| wait/synch/mutex/innodb/ibuf_pessimistic_insert_mutex | YES     | YES   |
+-------------------------------------------------------+---------+-------+

有关监视InnoDB互斥锁 await 的信息,请参见第 14.17.2 节“使用性能模式监视 InnoDB Mutexawait”