15.4.2 Change Buffer
Change buffer
是一种特殊的数据结构,当二级索引(secondary index)页发生更改时且受影响的页不在buffer pool
中,change buffer
用来缓存这部分的更改。由INSERT
, UPDATE
, DELETE
操作(DML)导致的缓存变化,会在其它读操作使将相关页加载到buffer pool
中后进行合并(merge)操作。
不像聚簇索引,二级索引通常是非唯一的,并且二级索引的插入操作相对随机。同样,删除和更新操作对二级索引页的更改在索引树中也不是顺序的。当其它(读)操作将相关的受影响的页加载到buffer pool
后,再对缓存的变化进行合并操作,避免了从磁盘读取二级索引页所需要的大量随机访问io。
系统空闲时,purge
操作定期将更新的索引页写入磁盘,索引页在slow shutdown
时,也会将更新的索引页写入磁盘。相比每个索引值变化立即写磁盘, purge
将一系列变化的索引值写入磁盘更加高效。
在有大量的索引需要更新或影响大量的行数时,change buffer merging
操作可能需要数小时。此时,磁盘的I/O会上升,会导致磁盘的相应变慢。change buffer merging
操作可以发生在事务提交后,server关机和重启之后,更多参考15.20.2 Forcing InnoDB Recovery
在内存中,change buffer
占用InnoDB buffer pool
的一部分。在磁盘上,它是系统表空间的一部分,因此在数据库重启期间,索引更改一直保持缓冲。
change buffer
缓存的数据(操作)类型由参数innodb_change_buffering
来配置,参考15.6.4 Configuring InnoDB Change Buffering。同样可以配置change bufer
的大小,参考15.6.4.1 Configuring the Change Buffer Maximum Size。
当二级索引包含降序索引列时或者主键包含降序索引列时,此时不支持change buffering
。
Change Buffer监控
- InnoDB标准状态信息输出有
change buffer
的相关状态信息。mysql> SHOW ENGINE INNODB STATUS\G
Change buffer
相关的信息在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
更多信息参考15.16.3 InnoDB Standard Monitor and Lock Monitor Output
以上的大部分信息同样可以在
INFORMATION_SCHEMA.INNODB_METRICS
表中看到。可以执行以下查询来获取相关的状态项及其介绍:SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%ibuf%'\G
关于
INNODB_METRICS
表的使用,参考15.14.6 InnoDB INFORMATION_SCHEMA Metrics TableINFORMATION_SCHEMA.INNODB_BUFFER_PAGE
表提供了buffer pool
中每个页的元数据信息,包括change buffer index and change buffer bitmap pages
。Change buffer
页可以通过PAGE_TYPE
来标识。IBUF_INDEX
是change buffer index
页,IBUF_BITMAP
是change buffer 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
表更多的信息,参考15.14.5 InnoDB INFORMATION_SCHEMA Buffer Pool Tables
- Performance Schema提供了change buffer mutex wait的高级性能监控:
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 mutex waits
的监控,参考15.15.2 Monitoring InnoDB Mutex Waits Using Performance Schema