(二)Mysql change buffer
序
change buffer
概念
写缓冲区 是针对于二级索引(辅助索引)页的更新优化措施
默认占用buffer 空间的 25%
change buffer 存储的是 对于二级索引页的变更操作,比如 insert/update/delete
首先 先想想上面的 黄色问题,想想之后再往下看
更新流程
第一种
更新的是唯一索引,没有办法缓存的,普通索引页的是可以记录到 change buffer的
为什么 写缓冲区,仅适用于二级索引页呢?
如果索引 设置了唯一性,进行修改的时候,就必须做唯一性校验(进行一次 磁盘 IO操作)
对于唯一索引来说,所有的更新操作都要先判断这个操作是否违反唯一性约束。比如,要插入 (name ="name01", id = 400) 这个记录,就要先判断现在表中是否已经存在 name=name01 的记录,而这必须要将数据页读入内存才能判断。如果都已经读入到内存了,那直接更新内存会更快,就没必要使用 change buffer 了。
普通索引的所有场景,使用 change buffer 都可以起到加速作用吗?
InnoDB 的数据是按数据页为单位来读写的。也就是说,当需要读一条记录的时候,并不是将这个记录本身从磁盘读出来,而是以页为单位,将其整体读入内存。
在 InnoDB 中,每个数据页的大小默认是 16KB。因为引擎是按页读写的,所以说,当找到 k=5 的记录的时候,它所在的数据页就都在内存里了。那么,对于普通索引来说,要多做的那一次“查找和判断下一条记录”的操作,就只需要一次指针寻找和一次计算。
当然,如果 k=5 这个记录刚好是这个数据页的最后一个记录,那么要取下一个记录,必须读取下一个数据页,这个操作会稍微复杂一些。但是,我们之前计算过,对于整型字段,一个数据页可以放近千个 key,因此出现这种情况的概率会很低。所以,我们计算平均性能差异时,仍可以认为这个操作成本对于现在的 CPU 来说可以忽略不计。
如果某次写入使用了 change buffer 机制,之后主机异常重启,是否会丢失 change buffer 和数据。
这个问题的答案是不会丢失,留言区的很多同学都回答对了。虽然是只更新内存,但是在事务提交的时候,我们把 change buffer 的操作也记录到 redo log 里了,所以崩溃恢复的时候,change buffer 也能找回来。
change buffer的大小 是多少?什么参数控制的?
change buffer 用的是 buffer pool 里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。
什么时候 会进行 merge 操作?
将change buffer中缓存的变更操作应用到对应的原数据页上,得到最新的数据页的过程,被称为merge
三种情况
原始数据页加载到了 Buffe Pool
系统有后台线程,定期进行merge
在数据库正常关闭的过程中,也会执行merge
change buffer的使用场景
- 写入数据之后 不会立刻读取它
- 写多读少的情况
- 数据库中大部分是非唯一索引的情况
想想 changge buffer 能用在我们平时开发的哪里呢?
写多读少,对于性能要求比较高,或者说并发比较高的,缓冲写操作导致的磁盘IO问题
写性能 有问题的时候,这是一个办法,进行一个缓存,批量处理,这不和MQ ,队列一个道理么
转载自:https://juejin.cn/post/7163567903504089124