InnoDB 的三大特性是:Buffer Pool、自适应 Hash 索引、双写缓冲区。
自适应 Hash 索引
自适应 Hash 索引,InnoDB 存储引擎内部自己去监控索引表,如果监控到某个索引经常用,那么就认为是热数据,然后内部自己创建一个 hash 索引,称之为自适应哈希索引( Adaptive Hash Index,AHI),创建以后,如果下次又查询到这个索引,那么直接通过 hash 算法推导出记录的地址,直接一次就能查到数据。
InnoDB 存储引擎使用的哈希函数采用除法散列方式,其冲突机制采用链表方式。
Buffer Pool
Buffer Pool,为了提高访问速度,MySQL 预先就分配/准备了许多这样的空间,为的就是与 MySQL 数据文件中的页做交换,来把数据文件中的页放到事先准备好的内存中。数据的访问是按照页(默认为 16KB)的方式从数据文件中读取到 buffer pool 中。Buffer Pool 按照最少使用算法(LRU),来管理内存中的页。
Buffer Pool 实例允许有多个,每个实例都有一个专门的 mutex 保护。Buffer Pool 中缓存的数据页类型有: 索引页、数据页、**undo 页、插入缓冲(insert buffer)、自适应哈希索引、InnoDB 存储的锁信息、数据字典信息(**data dictionary)等等。
双写缓冲区
双写缓冲区,是一个位于系统表空间的存储区域,在写入时,InnoDB 先把从缓冲池中的得到的 page 写入系统表空间的双写缓冲区。之后,再把 page 写到.ibd 数据文件中相应的位置。如果在 page 写入数据文件的过程中发生意外崩溃,InnoDB 在稍后的恢复过程中在 doublewrite buffer 中找到完好的 page 副本用于恢复。
doublewrite 是顺序写,开销比较小。所以在正常的情况下, MySQL 写数据page 时,会写两遍到磁盘上,第一遍是写到 doublewrite buffer,第二遍是从doublewrite buffer 写到真正的数据文件中。
它的主要作用是为了避免 partial page write(部分页写入)的问题。因为InnoDB 的 page size 一般是 16KB,校验和写入到磁盘是以 page 为单位进行的。而操作系统写文件是以 4KB 作为单位的,每写一个 page,操作系统需要写 4 个块,中间发生了系统断电或系统崩溃,只有一部分页面是写入成功的。这时 page 数据出现不一样的情形,从而形成一个”断裂”的 page,使数据产生混乱。