Py学习  »  DATABASE

Mysql 百问系列:Change Buffer 有什么作用

小歪同学 • 4 年前 • 311 次点击  
阅读 22

Mysql 百问系列:Change Buffer 有什么作用

问题

  1. change buffer 有什么作用?
  2. 什么情况下会用到change buffer


准备工作

 select * from information_schema.innodb_metrics where name like '%ibuf%';


可以查看到change buffer 的相关信息。

image.png
image.png


创建张表

CREATE TABLE `author_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),



    
  KEY `index_name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


author_1 有主键索引,和一个index_name 的二级索引。


假设该表存在以下数据


聚簇索引的结构类似于:

页6
1 2 3
abc jack zrr
234 24 23


我们知道二级索引 的value 存的是主键,例如此例子中二级索引的结构类似于:

页65
abc jack zrr
1 2 3



如果没有Change Buffer ,一条更新语句是如何执行的?


update


    
 author_1 set name = 'xxx' where id = 1


这个语句需要修改  2 个页面的数据。

  1. 第一处 是 聚簇索引 中的 id =1 条中的数据。
  2. 第二处 是 修改二级索引的 name 的数据。


更新流程是:

首先在 Buffer Pool 中查找对应的 页,(也就是页6, 和页65)

这里产生了2种情况:

  1. 页6 和 页 65 在Buffer Pool 中, 那么只要更新内存中的记录, 并写 redo log 。
  2. 页6 和 页 65 不在 Buffer Pool 中, 那么需要从磁盘中进行读取,放入内存后, 再修改, 并写redo log.

我们知道磁盘IO 比较耗时,所以Mysql 为了优化这一步骤,引入了Change Buffer 。


Change Buffer 作用场景

首先强调:

  • Change Buffer 是针对 非唯一的二级索引 的优化!
  • Change Buffer 是针对 非唯一的二级索引 的优化!
  • Change Buffer 是针对 非唯一的二级索引 的优化!


那么也就是 主键,以及唯一索引 是用不了这个优化的

对应到例子中, 即使引入了Change Buffer ,如果页6不在Buffer Pool 中,无论如何都需要从磁盘中读取,然后修改。

而页65,则不同了:

这个时候页65,不需要从磁盘中进行读取了,InnoDB 会直接写一条信息到Change Buffer 中,然后写redo log 。这样无需进行磁盘IO就可以完成更新。


总结下 Change Buffer  只有 对非唯一的二级索引 的数据页 ,并且该数据页不存在Buffer Pool 中,才会被使用到。


另外说明一点:change buffer 和 redo log 的数据为了持久化是会被刷入磁盘的。 也许会有疑问?这还不是进行磁盘操作了吗? 是进行磁盘操作了,但是change buffer 和 redo log 都是进行顺序写效率较高 (磁盘顺序写 和 随机写 性能差异很大)

修改后立即读取会如何?

select * from school where name = 'xxx'


由于会用到 index_name 索引, 所以需要将页65 读取到Buffer Pool ,但我们知道此时页面65页中 只有记录 'abc' ,那么读取页面65 之后,InnoDB 首先把 Change Buffer 中的数据 与读取的数据merge ,然后存储在Buffer Pool中,这个时候页65 中的数据就是正确的数据了。

为什么唯一索引无法使用Change Buffer ?

道理很简答, 唯一索引 在插入修改时都要进行唯一判断。如果不读取数据无法进行判断,既然数据无论如何都必须读取到Buffer Pool 中 自然就不会用到Change Buffer 了。

总结

change buffer  提升了对非唯一二级索引 的写性能。 如果业务上对字段没有唯一性要求,那么应该尽量使用普通索引,避免唯一索引。对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。这种业务模型常见的就是账单类、日志类的系统。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/52614
 
311 次点击