buffer_pool的结构:
change buff:
其中保存的是修改操作的动作
在查询的时候,change buffer是没有办法和innodb_buffer_pool查询一样缓存有数据直接返回的,因为change buffer记录的是修改操作这
个动作,并不是修改后的数据,所以即便change buffer中已经有了,在查询时也必须先将硬盘的数据读到缓存区,然后将change buffe
中的动作应用到缓存上,才能返回。
但是由于change buffer只记录动作,所以在修改时缓存中没有要修改的数据页也不要紧,直接在
change buffer中记下这个动作就可以了,在查询的时候才需要读硬盘
当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InooDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。
什么条件下可以使用 change buffer 呢?
唯一索引的更新就不能使用 change buffer,实际上也只有普通索引可以使用。
对于唯一索引来说,所有的更新操作都要先判断这个操作是否违反唯一性约束。比如,要插入 (4,400) 这个记录,就要先判断现在表中是否已经存在 k=4 的记录,而这必须要将数据页读入内存才能判断。如果都已经读入到内存了,那直接更新内存会更快,就没必要使用 change buffer 了。
change buffer 用的是 buffer pool 里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。
innodb插入新数据的流程:
如果要在这张表中插入一个新记录 (4,400) 的话,InnoDB 的处理流程是怎样的。
这个记录要更新的目标页在内存中
- 对于唯一索引来说,找到 3 和 5 之间的位置,判断到没有冲突,插入这个值,语句执行结束;
- 对于普通索引来说,找到 3 和 5 之间的位置,插入这个值,语句执行结束。
这个记录要更新的目标页不在内存中
- 对于唯一索引来说,需要将数据页读入内存,判断到没有冲突,插入这个值,语句执行结束;
- 对于普通索引来说,则是将更新记录在 change buffer,语句执行就结束了。
参考:
change buff 与buffer_pool有什么区别?
普通索引和唯一索引,应该怎么选择?