更改缓冲区是一个特殊的数据结构,它缓存了对次要索引页面的更改,当这些页面不在缓冲池中时。缓存的更改可能来自INSERT
、UPDATE
或DELETE
操作(DML),这些更改将在以后合并到缓冲池中。
与聚簇索引不同,次要索引通常是非唯一的,并且插入次要索引的顺序是随机的。类似地,删除和更新操作可能会影响次要索引页面,而这些页面在索引树中不是相邻的。将缓存的更改合并到以后读取缓冲池中的页面中,可以避免大量的随机访问I/O操作。
定期地,purge 操作在系统空闲或慢速关闭时将更新的索引页面写入磁盘。purge 操作可以更高效地写入磁盘块,而不是每个值都写入磁盘。
更改缓冲区合并可能需要几个小时,因为有许多受影响的行和许多次要索引需要更新。在这段时间内,磁盘I/O将增加,这可能会导致磁盘绑定的查询速度变慢。更改缓冲区合并也可能在事务提交后继续进行,甚至在服务器关闭和重新启动后(见第 17.20.3 节,“强制 InnoDB 恢复”)。
在内存中,更改缓冲区占用缓冲池的一部分。在磁盘上,更改缓冲区是系统表空间的一部分,其中缓存索引更改,当数据库服务器关闭时。
缓存在更改缓冲区中的数据类型由innodb_change_buffering
变量控制。有关更多信息,请参见配置更改缓冲区。您也可以配置最大更改缓冲区大小。有关更多信息,请参见配置更改缓冲区最大大小。
如果次要索引包含降序索引列或主键包含降序索引列,则不支持更改缓冲区。
有关更改缓冲区的常见问题,请参见第 A.16 节,“MySQL 8.3 FAQ: InnoDB 更改缓冲区”。
当执行INSERT
、UPDATE
和DELETE
操作时,索引列的值(特别是次要键的值)通常是无序的,需要大量的I/O操作来更新次要索引。更改缓冲区缓存次要索引条目的更改,当相关页面不在缓冲池中时,从而避免了昂贵的I/O操作。
因为它可以减少磁盘读取和写入,配置更改缓冲区对I/O绑定的工作负载非常有价值;例如,具有大量DML操作的应用程序,如批量插入操作,会从更改缓冲区中受益。
然而,变化缓冲区占用了缓冲池的一部分,减少了缓存数据页的可用内存。如果工作集几乎适合缓冲池,或者您的表具有相对较少的次要索引,那么禁用变化缓冲区可能是有用的。如果工作数据集完全适合缓冲池,变化缓冲区不会增加额外的开销,因为它只适用于不在缓冲池中的页。
变量 innodb_change_buffering
控制 InnoDB
执行变化缓冲区的程度。您可以启用或禁用插入、删除操作(当索引记录最初标记为删除时)和清除操作(当索引记录物理删除时)的缓冲区。更新操作是插入和删除的组合。默认的 innodb_change_buffering
值是 all
。
允许的 innodb_change_buffering
值包括:
-
all
默认值:缓冲插入、删除标记操作和清除操作。
-
none
不缓冲任何操作。
-
inserts
缓冲插入操作。
-
deletes
缓冲删除标记操作。
-
changes
缓冲插入和删除标记操作。
-
purges
缓冲后台物理删除操作。
您可以在 MySQL 选项文件(my.cnf
或 my.ini
)中设置 innodb_change_buffering
变量,或者使用 SET GLOBAL
语句动态地更改它,需要足够的权限来设置全局系统变量。请参阅 第 7.1.9.1 节,“系统变量权限”。更改设置将影响新的操作缓冲区;现有缓冲区条目的合并不受影响。
变量 innodb_change_buffer_max_size
允许配置变化缓冲区的最大大小作为缓冲池总大小的百分比。默认情况下,innodb_change_buffer_max_size
设置为 25。最大设置为 50。
考虑在 MySQL 服务器上增加 innodb_change_buffer_max_size
,其中插入、更新和删除活动频繁,变化缓冲区合并无法跟上新的变化缓冲区条目,导致变化缓冲区达到最大大小限制。
考虑减少 innodb_change_buffer_max_size
在 MySQL 服务器上,用于静态数据的报告,或者如果变化缓冲区消耗了太多与缓冲池共享的内存空间,导致缓冲池中的页面过早失效。
使用代表性工作负载测试不同的设置,以确定最佳配置。innodb_change_buffer_max_size
变量是动态的,可以在不重新启动服务器的情况下修改设置。
以下选项可用于变化缓冲区监控:
-
InnoDB
标准监控输出包括变化缓冲区状态信息。要查看监控数据,请发出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
有关更多信息,请参阅第 17.17.3 节,“InnoDB 标准监控器和锁监控器输出”。
-
信息模式
INNODB_METRICS
表提供了 InnoDB 标准监控器输出中的大多数数据点,以及其他数据点。要查看更改缓冲区指标和每个指标的描述,请发出以下查询:mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%ibuf%'\G
-
信息模式
INNODB_BUFFER_PAGE
表提供了缓冲池中每个页面的元数据,包括更改缓冲区索引和更改缓冲区位图页面。更改缓冲区页面由PAGE_TYPE
标识。IBUF_INDEX
是更改缓冲区索引页面的页面类型,而IBUF_BITMAP
是更改缓冲区位图页面的页面类型。Warning查询
INNODB_BUFFER_PAGE
表可能会引入显著的性能开销。为了避免影响性能,请在测试实例上重现您要调查的问题,然后在测试实例上运行查询。例如,您可以查询
INNODB_BUFFER_PAGE
表,以确定IBUF_INDEX
和IBUF_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_PAGE
表提供的其他数据的信息,请参阅第 28.4.2 节,“信息模式 INNODB_BUFFER_PAGE 表”。有关相关的使用信息,请参阅第 17.15.5 节,“InnoDB 信息模式缓冲池表”。 -
性能模式提供了更改缓冲区互斥等待仪表盘,以便进行高级性能监控。要查看更改缓冲区仪表盘,请发出以下查询:
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 互斥等待的信息,请参阅第 17.16.2 节,“使用性能模式监控 InnoDB 互斥等待”。