Skip to content

MySQL InnoDB Change Buffer (Insert Buffer) Note #53

Open
@Shellbye

Description

@Shellbye

最近开始读《MySQL技术内幕-InnoDB存储引擎》,感觉还是有很大的收获,读到 Insert Buffer(注:2015年已改为Change Buffer,书籍出版时间是2013)的时候,感觉收获挺大,在网上找了一些资料,这里做一点笔记。

概念解释

1.索引(Index

索引是数据库中非常关键的一个概念和技术,它在加速查询方面起着【至关重要】的作用。InnoDB中,所有的主键默认带有索引。主键的索引有一个别名叫聚集索引,非主键的其他列的索引叫辅助索引(secondary index)。

2.聚集索引(clustered index

如上所述,主键的索引一般叫聚集索引,为什么要用“聚集”这个词呢,我的理解是,因为主键往往的自增的,这就带来一个线下就是,索引在一个页的那些行,它们对应的行内容在磁盘也是在一个页的。这就比较类似书的目录和内容的关系,在目录上比较接近的部分,它们所指向的内容,也往往是比较接近的。比如第N章和第N+1章常常都是挨着的。这样的结构带来的一个好处就是在批量插入时,比如一次插入1000行数据,那么这1000行数据的主键肯定是连着的,那么它们的索引也很可能在一个页,最终它们的存储也恰好是在一个页,这样就可以用两次(一次写索引,一次写内容)磁盘IO(耗时)操作来完成,因为它们是连续的嘛。对于不连续的呢,就比较麻烦了。

3.辅助索引(secondary index

既然有聚集索引,那么对应的就有非聚集索引——辅助索引。辅助索引为什么不聚集呢,因为它们所对应的列很有可能并没有什么关系。就是说两个索引可能距离比较近,但是这和它们的内容所在位置是没有任何关系,这就类似汉语字典里面的用偏旁部首查字音一样,【打】和【答】可能在内容上比较近,但是它们对应的目录,也就是偏旁部首却距离很远,一个在提手旁“扌”对应的内容里,一个在竹字头“竹”对应的内容里,可以说是十万八千里了。在这种情况下,要批量插入1000行数据时,内容因为主键自增的关系,可能仍然可以通过一次磁盘IO就完成,但是我们的索引,却没有这么【聚集】,可能零零散散分布在若干个不同的页中,可能需要多次随机磁盘IO,这效率就低很多了,几乎是无法接收了,于是Change Buffer就出场了。

Change Buffer

1.Change Buffer的含义

为了避免上文描述的因为索引零散分布造成的多次随机磁盘IOMySQL InnoDB 引入了 Change Buffer,对于辅助索引的相关操作,并不会直接操作索引的页,而是先放到Change Buffer中,在以一定的频率和情况进行Change Buffer和索引的页的merge操作,这样可以将多个操作合并成一个,极大的提高了对于非聚集索引的操作性能。
下面的这个MySQL官方的图,很好的展示了这个过程
innodb-change-buffer

2.Change Buffer的配置

Change Buffer的缓冲的数据类型,由innodb_change_buffering配置,默认为all,表示包含所有类型,可选择的项有none,inserts,deletes,changes,purges,分别表示配置相应类型。

innodb_change_buffer_max_size用来配置Change Buffer可以占用buffer pool的最大百分比,默认为25,最大可以配置到50.

3.Change Buffer的监控

使用以下命令可以查看Change Buffer相关指标

mysql> SHOW ENGINE INNODB STATUS

在其输出的大量信息中,INSERT BUFFER AND ADAPTIVE HASH INDEX包含了Change Buffer相关的一些指标:

-------------------------------------
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

其中,size表示Change Buffer使用的页的数量,insert\delete mark\delete 分别表示各自的记录数,merges表示合并的次数。

参考资料

1.https://mysqlserverteam.com/the-innodb-change-buffer/
2.https://dev.mysql.com/doc/refman/5.7/en/innodb-change-buffer.html
3.https://dev.mysql.com/doc/refman/5.7/en/glossary.html
4.https://dev.mysql.com/doc/refman/8.0/en/faqs-innodb-change-buffer.html#faq-innodb-change-buffer-current-size

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions