更改缓冲区是一种特殊的数据结构,当辅助索引页面不在缓冲池中时,它会缓存对这些页面的更改。缓冲的更改可能是由INSERT
、UPDATE
或DELETE
操作(DML)引起的,稍后当其他读取操作将页面加载到缓冲池中时,这些更改将被合并。
与聚集索引不同,辅助索引通常是非唯一的,并且插入辅助索引的操作以相对随机的顺序进行。同样,删除和更新可能会影响未在索引树中相邻位置的辅助索引页面。稍后,当其他操作将受影响的页面读入缓冲池时,合并缓存的更改可以避免大量随机访问 I/O,否则需要从磁盘读取辅助索引页面到缓冲池中。
定期,当系统大部分时间处于空闲状态或在缓慢关闭期间运行的清除操作会将更新的索引页面写入磁盘。清除操作可以比立即将每个值写入磁盘更有效地为一系列索引值写入磁盘块。
当有许多受影响的行和大量辅助索引需要更新时,更改缓冲区合并可能需要几个小时。在此期间,磁盘 I/O 会增加,这可能会导致磁盘绑定查询的速度显着降低。更改缓冲区合并也可能在事务提交后继续进行,甚至在服务器关闭并重新启动后也会继续进行(有关更多信息,请参阅第 17.20.3 节“强制 InnoDB 恢复”)。
在内存中,更改缓冲区占用缓冲池的一部分。在磁盘上,更改缓冲区是系统表空间的一部分,当数据库服务器关闭时,索引更改会缓冲在此处。
更改缓冲区中缓存的数据类型由innodb_change_buffering
变量控制。有关更多信息,请参阅配置更改缓冲。您还可以配置最大更改缓冲区大小。有关更多信息,请参阅配置更改缓冲区最大大小。
如果辅助索引包含降序索引列或主键包含降序索引列,则不支持对该辅助索引进行更改缓冲。
有关更改缓冲区的常见问题的答案,请参阅第 A.16 节“MySQL 8.4 常见问题解答:InnoDB 更改缓冲区”。
当在表上执行INSERT
、UPDATE
和DELETE
操作时,索引列(尤其是辅助键的值)的值通常是无序的,需要大量的 I/O 才能更新辅助索引。更改缓冲区在相关页面不在缓冲池中时缓存对辅助索引条目的更改,从而避免了昂贵的 I/O 操作,因为它不会立即从磁盘读取页面。当页面加载到缓冲池中时,缓冲的更改将合并,并且更新后的页面稍后将刷新到磁盘。InnoDB
主线程在服务器几乎空闲时以及缓慢关闭期间合并缓冲的更改。
由于变更缓冲可以减少磁盘读写次数,因此对于 I/O 密集型工作负载来说,它非常有价值;例如,具有大量 DML 操作的应用程序(例如批量插入)将受益于变更缓冲。
但是,变更缓冲区会占用缓冲池的一部分,从而减少可用于缓存数据页的内存。如果工作集几乎适合缓冲池,或者如果您的表只有相对较少的二级索引,则禁用变更缓冲可能很有用。如果工作数据集完全适合缓冲池,则变更缓冲不会造成额外的开销,因为它仅适用于不在缓冲池中的页面。
innodb_change_buffering
变量控制 InnoDB
执行变更缓冲的程度。您可以启用或禁用插入、删除操作(在最初标记要删除索引记录时)和清除操作(在物理删除索引记录时)的缓冲。更新操作是插入和删除的组合。默认 innodb_change_buffering
值为 none
,允许的值在 innodb_change_buffering
文档中进行了描述。
您可以在 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
。
在用于报告的静态数据的 MySQL 服务器上,或者如果变更缓冲区占用了与缓冲池共享的内存空间过多,导致页面过早地从缓冲池中老化,请考虑减少 innodb_change_buffer_max_size
。
使用代表性的工作负载测试不同的设置,以确定最佳配置。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
是变更缓冲区位图页的页面类型。警告查询
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 节“INFORMATION_SCHEMA INNODB_BUFFER_PAGE 表”。有关相关使用信息,请参阅 第 17.15.5 节“InnoDB INFORMATION_SCHEMA 缓冲池表”。性能模式 为高级性能监控提供了变更缓冲区互斥锁等待检测。要查看变更缓冲区检测,请发出以下查询
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 互斥锁等待”。