概念:

Buffer Pool:由Innodb维护的一个缓存区,用来缓存数据和索引在内存中。大小控制参数:innodb_buffer_pool_size

 change buffer:是buffer pool中的一部分内存,可以在内存中有拷贝,也可以持久化到磁盘,大小控制参数:                        innodb_change_buffer_max_size,占buffer pool的百分比(这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%)

         当需要更新一个数据页时,如果数据页在内存中,则直接更新;否则,在不影响数据一致性的前提下,InnoDB 将这些操作缓存在 change buffer 中,这样就不必从磁盘中读取数据,当下次查询需要访问这个数据页时,再将数据页读入内存,然后执行 change  buffer 中与这个页有关的操作,最后将查询结果返回。

merge:将change buffer中操作应用到原始页,得到最新结果的过程称为merge。merge触发事件:1.访问这个数据页;2.后台线程定期 ;3.数据库正常关闭(shutdown)的过程。

 

使用条件:

    对于唯一索引,所有的更新操作都要先判断这个操作是否违反唯一性约束。比如要插入一条记录,必须将这个数据页读入内存才能判断。已经读入内存了,直接更新内存更快。就没必要使用change buffer了。对于普通索引,直接将更新记录在change buffer,语句执行就结束了。结论:唯一索引的更新不能使用change buffer,实际只有普通索引可以使用。

注意点:假设一个业务的更新模式是写入之后马上会做查询,那么即使满足了条件,将更新先记录在 change buffer,但之后由于马上要访问这个数据页,会立即触发 merge 过程。这样随机访问 IO 的次数不会减少,反而增加了 change buffer 的维护代价

 

change buffer 和redo log:

 change buffer 主要节省的是随机读磁盘的IO 消耗:

           第一种情况:要更新的记录目标页在内存中,不管是唯一索引,还是普通索引,性能影响极小(唯一索引只是在内存数据中判断有没有冲突)

           第二种情况:要更新的记录目标页不在内存中,对于唯一索引,必须将数据也读入内存进行判断是否冲突,而对于普通索引,直接将更新记录在changge buffer,语句就结束了。将数据从磁盘读入内存涉及随机 IO 的访问,是数据库里面成本最高的操作之一。change buffer 因为减少了随机磁盘访问,所以对更新性能的提升是会很明显的。

redo log (WAL[write ahead log])主要是节省随机写磁盘的IO消耗:

             当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面(这个过程是顺序写入磁盘,效果会高很多)