InnoDB 概述
Table of Contents

内存

InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可将其视为基于磁盘的数据库系统(DiskbaseData base)。在数据库系统中,由于CPU速度与磁盘速度之间的鸿沟,基于磁盘的数据库系统通常使用缓冲池技术来提高数据库的整体性能 。

缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页“FIX”在缓冲池中。下一次再读相同的页时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。

对于数据库中页的修改操作,则首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上。这里需要注意的是,页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时触发,而是通过一种称为Checkpoint的机制刷新回磁盘。同样,这也是为了提高数据库的整体性能。

缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、I nnoDB存储的锁信息(lock info)、数据字典信息(data dictionary)等。

check point 技术

刷新脏页开销很大,同时为了避免刷页过程中宕机丢失数据的问题,事务型数据库普遍采用 Write Ahead Log 策略,即当事务提交时,先写重做日志,再修改页。

当数据库宕机时,数据库只需要对 check point 之后的重做日志进行恢复,缩短了恢复时间。

Fuzzy Checkpoint 类型

Master Thread 工作方式

InnoDB 存储引擎的主要工作都是在单独的后台线程 Master Thread 中完成的,主要工作包括:

InnoDB 关键特性

插入缓冲

在插入记录时,需要同时插入索引,对于非聚集非唯一的辅助索引来说,需要离散地访问非聚集索引页,导致插入性能下降。

Insert Buffer 的机制:对于非唯一辅助索引的插入或更新操作,如果发现该索引页没有在缓存池中,则直接插入,否则就存放到 Insert Buffer 中。然后按照一定频率将 Insert Buffer 中的数据合并到辅助索引中。

Insert Buffer 的数据结构是 B+ 树。

两次写

写页到磁盘的时候宕机会导致部分写失效,这时候由于该页已经损坏了,无法利用重做日志进行还原。重做日志记录的是对页的物理操作,在页损坏的情况是不能还原的。

为了解决这个问题,InnoDB 使用了 doublewrite。简单来说,就是在刷盘之前,先将脏页写入到 doublewrite buffer(2MB),再刷入到共享表空间的磁盘中,该过程是顺序写,开销很小。完成 doublewrite的之后,再将脏页分别写入到各个表空间中。本质上就是在刷页之前对脏页做备份。

自适应哈希索引

InnoDB存储引擎会监控对表上各索引页的查询。如果观察到建立哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索 引(Adaptive Hash Index,AHI)。AHI是通过缓冲池的B+树页构造而来,因此建立的速度很快,而且不需要对整张表构建哈希索引。In noDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引。

AHI有一个要求,即对这个页的连续访问模式必须是 一样的。例如对于(a,b)这样的联合索引页,其访问模式可以是以下情况:

访问模式一样指的是查询的条件一样,若交替进行上述两种查询,那么InonDB存储引擎不会对该页构造AHI。此外AHI还有如下的要求:

异步 IO

为了提高磁盘操作性能,InnoDB 采用异步IO来处理磁盘操作。

InnoDB 逻辑存储结构

InnoDB 逻辑存储结构

VARCHAR 长度

VARCHAR(N)中的N指的是字符长度,其实际占用的字节数量跟编码有关。而VARCHAR的最大长度官方文档中是65535字节,而且该最大长度是所有VARCHAR列共享的。