1.概述
innodb主要有两种线程 Master Thread(刷新内存到磁盘)和 IO Thread (处理磁盘请求的IO)。
innodb是利用磁盘存储的,但是磁盘操作满,提供了大量的缓存,来减少这个速度的鸿沟。
1.1 innodb的内存:
缓冲池:
1.2 LRU List、Free List和Flush List:
LRU List:
缓冲池是通过LRU(Latest Recent Used,最近最少使用)算法来进行管理的。用来存储被查询出来的page的。
**实现:**但是和其不同的,会通过midpoint来标识(差不多3/8的位置),但第一次查询出来的数据,不会放在list的最前端,而是放在midpoint的位置,然后当innodb_old_blocks_time的时间配置,过一段时间会被刷到最前端。利用midpoint的好处主要是为了,防止某一次表扫描仅仅只利用一两次,就将数据刷到最前端,把热点数据刷掉的。一般的命中率不低于95%的。
在LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页的数据产生了不一致。这时数据库会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的页即为脏页列表。
**Free List:**表示还没有被利用的内存列表。
**Flush List:**Flush列表中的页即为脏页列表。
**区别:**在LRU列表中的页被修改后,称该页为脏页(dirty page),即缓冲池中的页和磁盘上的页的数据产生了不一致。这时数据库会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的页即为脏页列表。需要注意的是,脏页既存在于LRU列表中,也存在于Flush列表中。LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者互不影响。
1.3 Checkpoint技术
解决问题:
❑缩短数据库的恢复时间;
❑缓冲池不够用时,将脏页刷新到磁盘;
❑重做日志不可用时,刷新脏页。
实现: 而Checkpoint所做的事情无外乎是将缓冲池中的脏页刷回到磁盘。不同之处在于每次刷新多少页到磁盘,每次从哪里取脏页,以及什么时间触发Checkpoint。
1.4 innodb的关键特性
InnoDB存储引擎的关键特性包括:
❑插入缓冲(Insert Buffer)
❑两次写(Double Write)
❑自适应哈希索引(Adaptive Hash Index)
❑异步IO(Async IO)
❑刷新邻接页(Flush Neighbor Page)
插入缓存:
存在问题:插入聚集索引很快,而一个表会有多个非聚集索引,而都是离散随机访问的,所以很慢。
解决问题:加快非聚集索引的插入或者更新。
实现:若非聚集索引页在内存缓冲池,则直接更新。若不在,则先方到inser buffer,然后通过异步方式再插入索引。
两次写入:
存在问题:page写入磁盘时候发生宕机,会导致page写入不完整。
解决问题:保证了数据的完整性和可靠性。
实现:将要写入的page先copy到内存的doublewrite buffer,然后将从内存写到磁盘的doublewrite(过程是顺序写入,开销不大),然后再内存的doublewrite buffer写入离散的磁盘。(顺序写入与随机写入的性能差异巨大,上百或千倍)
自适应哈希索引:
存在问题:不算存在的问题,只是优化查询热点数据。root到叶子的多次的遍历。
解决问题:减少热点数据回表时候,从root到叶子的多次的遍历,即减少叶子读取,即会减少io。
实现方案:(Adaptive Hash Index,AHI)利用一定的监控机制对索引监控,当达到一定的时机促发,建立index hash来存储热点的索引键值和page的Hash映射关系,然后查询时候通过索引键值查询这个表,迅速定位到page。无论只是涉及到热点主键查询都会优化,回表也是。
异步IO:
为了提高磁盘操作性能,当前的数据库系统都采用异步IO(Asynchronous IO,AIO)的方式来处理磁盘操作。InnoDB存储引擎亦是如此。
例子: 如果用户发出的是一条索引扫描的查询,那么这条SQL查询语句可能需要扫描多个索引页,也就是需要进行多次的IO操作。在每扫描一个页并等待其完成后再进行下一次的扫描,这是没有必要的。用户可以在发出一个IO请求后立即再发出另一个IO请求,当全部IO请求发送完毕后,等待所有IO操作的完成,这就是AIO。
刷新邻接页:
当刷新一个脏页时,InnoDB存储引擎会检测该页所在区(extent)的所有页,如果是脏页,那么一起进行刷新。这样做的好处显而易见,通过AIO可以将多个IO写入操作合并为一个IO操作。