暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

内存结构:Change Buffer

我与风来 2021-06-28
709

更改缓冲区是一种特殊的数据结构,当二级索引页不在缓冲池中时,它会缓存这些页的更改。缓冲的更改可能是由插入、更新或删除操作(DML)引起的,稍后当页面被其他读取操作加载到缓冲池时,这些更改将被合并。


与聚集索引不同,二级索引通常是非唯一的,二级索引中的插入是以相对随机的顺序进行的。类似地,删除和更新可能会影响索引树中不相邻的二级索引页。稍后,当受影响的页被其他操作读入缓冲池时,合并缓存的更改可避免从磁盘将二级索引页读入缓冲池所需的大量随机访问I/O。

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

当有许多受影响的行和许多次索引要更新时,更改缓冲区合并可能需要几个小时。在此期间,磁盘I/O会增加,这可能会导致磁盘绑定查询的速度显著减慢。提交事务后,甚至在服务器关闭并重新启动后,更改缓冲区合并也可能继续发生(强制 InnoDB 恢复)。

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

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

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

配置更改缓冲

在表上执行 INSERT、UPDATE 和 DELETE 操作时,索引列的值(特别是二级键的值)通常按未排序的顺序排列,需要大量的I/O才能使二级索引更新。当相关页不在缓冲池中时,change buffer 缓存对二级索引项的更改,从而避免了昂贵的I/O操作,因为它不会立即从磁盘读取页。当页面加载到缓冲池时,缓冲的更改被合并,更新的页面稍后被刷新到磁盘。InnoDB 主线程在服务器接近空闲时以及在缓慢关闭期间合并缓冲的更改。

因为它可以减少磁盘读写,所以更改缓冲对于I/O绑定的工作负载最有价值;例如,具有大量 DML 操作(如大容量插入)的应用程序受益于更改缓冲。

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

innodb_change_buffering
 变量控制 innodb 执行更改缓冲的范围。您可以启用或禁用插入缓冲、删除操作(当索引记录最初标记为删除时)和清除操作(当索引记录被物理删除时)。更新操作是插入和删除的组合。默认的 innodb_change_buffering
缓冲值是all。

允许的 innodb_change_buffering
 包括:

  • all: 默认值:缓冲区插入、删除标记操作和清除

  • none: 不要缓冲任何操作

  • inserts: 缓冲区插入操作

  • deletes: 缓冲区删除标记操作

  • changes: 缓冲插入和删除标记操作

  • purges: 缓冲在后台发生的物理删除操作

配置更改缓冲区最大大小

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

考虑在具有大量 insert、update 和 delete 活动的MySQL服务器上增加 innodb_change_buffer_max_size
,其中change buffer合并不能跟上新的 change buffer 条目,导致 change buffer 达到其最大大小限制。

在使用静态数据进行报告的 MySQL 服务器上,考虑减小 innodb_change_buffer_max_size
,或者如果change buffer占用了与缓冲池共享的太多内存空间,导致页面在缓冲池中的老化时间比预期的要早。

使用具有代表性的工作负载测试不同的设置,以确定最佳配置。innodb_change_buffer_max_size
变量是动态的,允许在不重新启动服务器的情况下修改设置。


文章转载自我与风来,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论