InnoDB的逻辑存储结构如下图所示:
当我们建立一个表,引擎选择为InnoDB时,MySQL会为我们产生一个表名.idb文件,这个文件就是表空间:存放数据+索引+表结构。
表空间
段
区
页
行
下面是InnoDB架构图,左侧为内存结构,右侧为磁盘结构,为了防止直接操作磁盘,MySQL会先把数据缓存到内存中,然后再一定的时机通过异步IO将数据写入磁盘,提高效率。
在左侧的内存结构中,主要分为这么四大块儿: Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer。 接下来介绍一下这四个部分,Adaptive Hash Index自适应哈希索引是用来提高效率,我们可以暂时不用了解。
Buffer Pool
缓冲池 Buffer Pool,是内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增 删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频率刷新到磁盘,从而减少磁盘IO,加快处理速度。
缓冲池以Page页为单位,底层采用链表数据结构管理Page。根据状态,将Page分为三种类型:
Change Buffer
我们先看一幅图:这个是二级索引的结构图
与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引。同样,删除和更新 可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了 ChangeBuffer之后,我们可以在缓冲池中进行合并处理,减少磁盘IO。
Log Buffer。
innodb_flush_log_at_trx_commit:日志刷新到磁盘时机,取值主要包含以下三个:
这里一定要记住,LogBuffer是默认在事务每次提交时将缓存区的数据写入磁盘。方便以后对事务的理解
Undo Tablespaces
撤销表空间,MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储 undo log日志。
Doublewrite Buffer Files
双写缓冲区,innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件 中,便于系统异常时恢复数据。
Redo Log
重做日志,是用来实现事务的持久性。该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所 有修改信息都会存到该日志中, 用于在刷新脏页到磁盘时,发生错误时, 进行数据恢复使用。
在InnoDB的后台线程中,分为4类,分别是:Master Thread 、IO Thread、Purge Thread、 Page Cleaner Thread。
Master Thread
核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中, 保持数据的一致性, 还包括脏页的刷新、合并插入缓存、undo页的回收 。
IO Thread
Purge Thread
主要用于回收事务已经提交了的undo log,在事务提交之后,undo log可能不用了,就用它来回 收。
Page Cleaner Thread
协助 Master Thread 刷新脏页到磁盘的线程,它可以减轻 Master Thread 的工作压力,减少阻 塞。
下节,我们将介绍,redo log,undo log,mvcc和两个隐藏字段如何实现事务的四大特性。