2.6 InnoDB关键特性
- 插入缓冲
- 两次写
- 自适应哈希索引
- 异步IO
- 刷新邻接页
2.6.1 插入缓冲
通常应用程序中行记录的插入顺序是按照主键的递增顺序进行插入的,因此插入聚集索引(Primary Key)一般是顺序的,不需要磁盘的随机读取,但是对于非聚集非唯一的索引的插入不再是顺序的,由于随机读取的存在导致了插入的性能下降。
于是开创了Insert Buffer , 对于非聚集索引的插入和更新操作并不是每一次都插入到索引页中, 而是先判断非聚集索引页是否在缓冲池中,若在,则直接插入;若不在,则先放到一个Insert Buffer对象中,然后以一定的频率进行Insert Buffer和辅助索引子节点的merge操作,这样多个插入操作就合并成为了一个操作(因为在一个索引页中) 大大提高了非聚集索引的插入性能。
Insert Buffer 内部实现是一个B+树,Mysql4.1 一张表就有一颗Insert Buffer B+树,现在是全局就一颗Insert Buffer B+树。非叶子节点存储的是Search Key,叶子节点是各字段数据记录。
- 非叶子节点: space+marker+offset
- 叶子节点:space+marker+offset+metadata+secondary index recored\
2.6.2 两次写
double write 提升了innodb的稳定性,未使用两次写技术之前,出现过部分写失败而丢失数据的情况,即innodb正在写某个页到列表中,这个页只写了一部分,就发生了宕机。此时通过redo日志也无法挽救,因为这个页本身已经损坏了,重做毫无意义。正确的做法是,需要一个页的副本,当写入失败的时候,先通过备份的页来还原该页,然后在用redo进行重做,这就是double write .
double write 一共有两部分组成,一部分是内存中的double write buffer , 另一部分是物理磁盘上的共享表空间里面128个连续的页,大小都为2MB。写入方法为:刷新脏页时,并不直接写磁盘,通过memcpy函数复制到double write buffer中,然后double write buffer再分两次,每次1MB写入到共享表空间的物理磁盘上,double write 页是连续的,所以性能较高。
2.6.3 自适应哈希索引
哈希是一种非常快的查找方法,一般情况下查找的时间复杂度为O(1) , 而B+的查找次数取决于B+树的高度,在生产环境中,B+树一般3~4层。
InnoDB会监控各表索引页的查询情况,自动建立哈希索引,所以称为自适应哈希索引(AHI), AHI通过缓冲池的B+树页构造层,建立速度很快。
但是AHI要求连续,比如
where a=xxx
where a=xxx and b=xxx
连续出现会创建, 交替出现不会创建AHI
2.6.4 异步IO
比如一个用户发出一条索引扫描的查询,涉及到扫描多个索引页,也就是需要进行多次的IO操作,等一个页扫描完成再进行下一个是非常不明智的。全部IO请求发送完成后,等待IO的结果,这是AIO。AIO还可以将多个IO操作合并为一个,可以提高IOPS的性能。linux上可以通过iostat命令查看当前的IO情况
2.6.5 刷新邻接页
当刷新一个脏页的时候,innodb引擎会检测该页所在区(ext)的所有页,如果有脏页,就一起刷新。并通过AIO将多个IO合并为一个IO。