InnoDB存储引擎会监控对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引-gt;通过缓冲池的B+树构造,
1、插入缓冲Insert Buffer--给InnoDB存储引擎带来了性能
插入缓冲和数据页一样,是物理页的一个组成部分。
(1)主键primary key是行唯一的标识符,在应用程序中行记录的插入顺序是按照主键递增的顺序进行插入的->插入聚集索引一般是顺序的,不需要磁盘随机读取。
(2)非聚集的辅助索引secondary index不唯一,进行插入操作时,非聚集索引叶子结点的插入不是顺序的,折旧需要离散的访问非聚集索引页,插入性能低(B+树的特性决定了非聚集索引的离散性)
插入缓冲->对于非聚集索引的插入或更新操作,不是每一次直接插入,而是先判断插入的非聚集索引页是否在缓冲池中,在则直接插入;否则先放入一个插入缓冲区中,再以一定的频率执行插入缓冲和非聚集索引叶子结点的合并。
mysql> show engine innodb status;
...
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 7545, free list len 3790, seq size 11336,
8075308 inserts, 7540969 merged recs, 2246304 merges
...
7545已用,3790空闲,11336插入缓冲大小=7545+3790,8075308插入的记录数,7540969合并的页的数量,2246304合并的次数,7540969:2246304≈3:1
注:插入缓冲默认情况下最大可以占用1/2的缓冲池内存,可修改IBUF_POOL_SIZE_PER_MAX_SIZE进行控制。
插入缓冲使用的条件:
(1)索引是辅助索引;
(2)索引不是唯一的。
2、两次写Double Write--给InnoDB存储引擎带来数据的可靠性
部分失效partial page write:当数据库宕机时,数据库正在写一个页面且只写了一部分导致数据丢失->根本原因是mysql的page size跟系统文件的page size不一致,导致在写数据时,系统并不是把整个buffer pool page一次性写到disk上。(比如16K的页,只写了前4K)
重做日志redo log:记录的是对页的物理操作,如偏移量800,写'AAA'记录,即如果这个页本身已经损坏,再对其进行重做已经没有任何意义。
两次写double write:在应用apply重做日志前,我们需要一个页的副本,当写入失效发生时,先通过副本来还原该页,再进行重做,这就是double write。
恢复工作方式:如果是写doublewrite buffer本身失效,那么这些数据不会被写到磁盘,innodb此时会从磁盘载入原始数据,然后再通过log files计算出正确的数据,重新写入到doublewrite buffer;如果是写磁盘失败,则直接用buffer的数据再写一遍。
doublewrite架构如下图所示:
参考: