MySQL学习(六)change-buffer

文章部分总结描述来自参考文章,属于半原创。

概述

????文章将会介绍 change buffer 相关的知识点

查看 MySQL InnoDB 状态的命令

SHOW ENGINE INNODB STATUS;

这个命令可以查看带InnoDB 引擎当前线程和 buffer pool 的一些状态,对于学习MySQL 很有帮助。(里面的参数都搞懂了就差不多了,哈哈哈)

Change Buffer 是什么

????我们更新一条记录的时候,首先会去buffer pool 寻找这条数据,假如该数据存在,那么直接更新在内存中的纪录(合适的时候会回刷)。但是要是buffer pool 不存在呢 ?MySQL 为了避免每次遇到这样的情况都会去磁盘上加载数据,于是就设计了 change buffer , 通俗地说就是先将对纪录的更改操作暂时纪录在 change buffer ,待合适的时候再进行回刷回磁盘,提高更新操作的性能。????官方文档描述The change buffer is a special data structure that caches changes to secondary index pages when those pages are not in the buffer pool. The buffered changes, which may result from INSERT, UPDATE, or DELETE operations (DML), are merged later when the pages are loaded into the buffer pool by other read operations.????通过上面的描述可以知道

  • change buffer 用于 secondary index
  • change buffer 用于 INSERT ,UPDATE ,DELETE 操作,并且将会在适当的时刻 merge,当出现的读操作的时候,数据会从磁盘加载进 buffer pool ,然后应用上 change buffer 。

Change Buffer 的例子 (来自 MySQL 45 讲)

假如我们执行以下的语句。

mysql> insert into t(id,k) values(id1,k1),(id2,k2);

分析这条更新语句,你会发现它涉及了四个部分:内存、redo log(ib_log_fileX)、 数据表空间(t.ibd)、系统表空间(ibdata1)。

这条更新语句做了如下的操作(按照图中的数字顺序):

  • Page 1在内存中,直接更新内存;

  • Page 2没有在内存中,就在内存的change buffer区域,记录下“我要往Page 2插入一行”这个信息

将上述两个动作记入redo log中(图中3和4)。

做完上面这些,事务就可以完成了。所以,你会看到,执行这条更新语句的成本很低,就是写了两处内存,然后写了一处磁盘(两次操作合在一起写了一次磁盘),而且还是顺序写的。

select * from t where k in (k1, k2)

从图中可以看到:

  1. 读Page 1的时候,直接从内存返回。有几位同学在前面文章的评论中问到,WAL之后如果读数据,是不是一定要读盘,是不是一定要从redo log里面把数据更新以后才可以返回?其实是不用的。你可以看一下图3的这个状态,虽然磁盘上还是之前的数据,但是这里直接从内存返回结果,结果是正确的。

  2. 要读Page 2的时候,需要把Page 2从磁盘读入内存中,然后应用change buffer里面的操作日志,生成一个正确的版本并返回结果。

可以看到,直到需要读Page 2的时候,这个数据页才会被读入内存。

Change Buffer 如何工作

使用场景

针对写多读少的场景,因为写多的情况操作全都操作change buffer , 而假如想上面例子中的更改缓存在 change buffer , 下一刻 马上要进行读取,那么 change buffer 就失去了作用,因为我们读取的操作会从吃破案加载数据到 buffer pool .

Change Buffer 与 redo-log

** redo log 主要节省的是随机写磁盘的IO消耗(转成顺序写),而change buffer主要节省的则是随机读磁盘的IO消耗。 **

参考资料

  • MySQL45讲
  • https://dev.mysql.com/doc/refman/8.0/en/innodb-change-buffer.html (Change Buffer)

相关推荐