文章目录
- 前言
- 一、插入缓存
- 二、两次写
- 三、自适应哈希索引
- 四、异步IO
- 五、刷新邻接页
- 六、结语
前言
本文主要是偏MySQL本身的底层设计较多,较为枯燥,但是又比较重要,还是静心看吧,哈哈
InnoDB作为MySQL使用最广泛的存储引擎,其重要程度和江湖地位无需再多说什么,那么今天就聊一聊InnoDB的一些关键特性。
另外一说到数据库的特性,肯定就是他的优点,他为啥牛X,为啥速度会快,为啥性能会稳定等等,知道了为什么就能更好的解决问题。
一、插入缓存
听名字就知道是在插入的时候起作用的,既然说到缓存那肯定就涉及到异步,所以最直观的感受就是,插入数据时不直接刷新到磁盘,而是先缓存起来,等到一定阈值时再一起刷盘,实际情况也就是这样的。但是需要注意的是 这里的缓存并不是内存,而是和数据页一样,即物理页的组成部分。
另外对于聚集索引(说到聚集索引一般都说的主键),如果主键是自增的,那么就是顺序插入,性能非常高,一般是没有啥问题的,像分布式系统中雪花算法就是利用这一特性的,所以插入缓存肯定不是为了顺序插入做的优化。
插入缓存主要还是为了解决非聚簇索引的插入速度问题,非聚簇索引的值由于不是递增的,所以在插入的时候就肯定不是顺序的,而是随机的,涉及到随机就涉及到寻址,在大量插入的情况下速度就非常糟糕,那么怎么去解决这个问题呢?相信大家已经知道。
插入缓存使用有两个限制条件:
(1)索引是二级索引或者叫辅助索引
(2)索引不是唯一的
索引为什么是二级索引?是一级索引的话,本身数据库中的行就是按照一级索引排序的。
为什么索引需要唯一?如果是唯一索引那么在插入的时候就需要查数据库是否有相同值得记录,也就失去了意义。
下面部分的内容要不要写还是纠结了一会,不写感觉不完整,写了感觉插入缓存章节文字太多,进一步导致整篇文章的文字过多,还是写吧,感兴趣的可以啃一啃:
插入缓存带来的问题就是,在大量插入的业务下,会导致插入缓存占用过多缓冲池的内存(最大可以到1/2),
从1.0.x版本开始引入了Change Buffer,可将其视为Insert Buffer的升级,从这个版本开始,InnoDB存储引擎可以对DML操作–INSERT、DELETE、UPDATE都进行缓冲,分别对应Insert buffer、Delete Buffer、Purge buffer。
另外InnoDB存储引擎提供参数innodb_change_buffering来开启各种buffer,其对应的参数有inserts,deletes,purges,changes,all,none。
1.all
The default value: buffer inserts, delete-marking operations, and purges.
2.none
Do not buffer any operations.
3.inserts
Buffer insert operations.
4.deletes
Buffer delete-marking operations.(包括delete和update操作)
5.changes
Buffer both inserts and delete-marking.
6.purges
Buffer the physical deletion operations that happen in the background
二、两次写
两次写:简单说就是一次写共享表空间的物理磁盘,一次写各个表空间文件中。
doublewrite由两部分组成,一部分是内存中的doublewrite,大小为2M,一部分是磁盘上共享表空间中的连续128个页,即2个区大小也为2M。在刷新缓冲池的脏页时并不直接写盘,而是通过memcpy函数将脏页复制到内存中的doublewrite缓存,之后doublewrite缓存再分两次,每次1M顺序地写入共享表空间的物理磁盘上。doublewirte写入共享表空间时空间是连续的,因此速度非常快。写完之后在将doublewrite buffer写入各个表空间,此时写入就不是连续的了,需要自行查找。
三、自适应哈希索引
既然是自适应,那么肯定就是数据根据一定的触发条件自己进行的优化,另外hash是一种非常快速的查找方法,一般的时间复杂度为O(1)。
InnoDB引擎会监控对表上各个索引页的查询。如果发现建立哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引。其是通过缓冲池的B+树页构造,因此建立的速度很快。引擎会根据情况对某些热点数据来建索引。
自适应hash有以下要求:
(1)以相同的模式连续运行,模式指的是查询条件一模一样;
(2)以该模式访问了100次;
(3)页通过该模式访问了m次,m=页中记录/16
此外可以通过show engine innodb status来查看当前自适应hash的使用情况。
四、异步IO
异步IO主要是提高了磁盘的访问效率,每次请求的时候不需要等待,而且可以合并操作,也可以大大提高磁盘的访问效率。
五、刷新邻接页
InnoDB在刷新脏页的时候,会检查该页所在区的所有页,如果是脏页的话就一并刷新。因为这样可以将这几个页的刷新操作合并成一个,显著提高了性能。但是这样也会存在一些问题:
(1)相邻的页不是太脏,即新数据不是那么多,刷新之后又变成脏页了?
(2)固态盘有很高的IOPS,是否还需要这个特性呢?
InnoDB在1.2.X版本提供了innodb_flush_neighbors,用来控制是否启用该特性。机械盘建议开启,固态盘建议关闭。
六、结语
道阻且长,行则将至,行而不辍,未来可期,加油。