MySQL—InnoDB的体系架构

InnoDB体系架构

InnoDB存储引擎是一个完整支持ACID事务的MySQL存储引擎, 其特色是 行锁设计, 支持MVCC, 支持外键, 提供一致性非锁定读, 同时被设计用来最有效的利用以及使用内存和CPU前端

1.InnoDB体系架构

在这里插入图片描述

图中简单显示了InnoDB的存储引擎的体系架构, 从图中可见,InnoDB有多个内存块, 能够认为这些内存块组成了一个大的内存池, 负责以下工做 :web

  • 维护全部进程/线程须要访问的多个内部数据结构
  • 缓存磁盘上的数据, 方便快速地读取, 同时在对磁盘文件的数据修改以前在这里缓存
  • 重作日志(redo log)缓冲

后台线程的主要做用是负责刷新内存池中的数据, 保证缓冲池中的内存缓存是最新的数据.此外将已修改的数据文件刷新到磁盘文件, 同时保证数据库发生异常的状况下InnoDB能恢复到正常运行状态算法

1>后台线程

InnoDB存储引擎是多线程的模型, 所以后台有多个不一样的后台线程, 负责处理不一样的任务数据库

  • Master Thread缓存

    主要负责将缓冲池的数据异步刷新到磁盘, 保证数据的一致性, 包括脏页的刷新, 合并插入缓冲(INSERT BUFFER), UNDO页的回收数据结构

  • IO Thread多线程

    在InnoDB存储引擎中大量使用了AIO(Async IO)来处理写IO请求, 这样能够大大提升数据库性能. 而IO Thread的工做主要是负责这些IO请求的回调(call back)处理, 有四种IO Thread : write, read, insert buffer, log IO Thread.架构

  • Purge Thread并发

    事务在提交后, 其所使用的undolog可能再也不须要, 所以须要PurgeThread来回收已经使用并分配的undo页.异步

    InnoDB1.1以前 : purge操做在Master Thread中完成, InnoDB1.1开始能够独立到单独的线程中进行.

  • Page Cleaner Thread

    将以前版本中脏页的刷新操做都放入到单独的线程中来完成

2>内存

InnoDB存储引擎是基于磁盘存储的, 并将其中的记录按照页的方式进行管理. 所以能够将其视为基于磁盘的数据库系统(Disk-base Database). 在数据库系统中, 因为CPU速度与磁盘速度之间的鸿沟, 基于磁盘的数据库系统一般使用缓冲池技术来提升数据库的总体性能.

  • 缓冲池

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

对于数据库中页的修改操做, 首先修改在缓冲池中的页, 而后再以必定的频率刷新到磁盘上.是经过一种叫作CheckPoint的机制刷新回磁盘,提升数据库的总体性能.

在这里插入图片描述

具体来看, 缓冲池中缓存的数据页类型有:索引页,数据页,undo页,插入缓冲(insert buffer),自适应哈希索引(adaptive hash inddex),InnoDB存储的锁信息(lock info),数据字典信息(data dictionary)等,在InnoDB 1.0.x开始, 容许有多个缓冲池实例,每一个页根据哈希值平均分配到不一样的缓冲池实例中,这样作的好处是减小数据库内部的资源竞争,增长数据库的并发处理能力

  • LRU List, Free List, Flush List

数据库的缓冲池是经过LRU(Latest Recent Used, 最近最少使用)算法来进行管理的. 即最频繁使用的页在LRU列表的前端,而最少使用的页在LRU列表的尾端. 当缓冲池不能存放新读取到的页时, 将首先释放LRU列表中尾端的页

在InnoDB存储引擎中, 缓冲池中页的大小默认为 16KB, 一样使用LRU算法对缓冲池进行管理,不一样的是, 在InnoDB中,加入了midpoint位置. 新读取的页不直接放到LRU列表的首部, 而是放到midpoint位置,默认实在LRU列表的5/8处. midpoint以后的列表称为old列表, 以前的列表称为new列表,能够简单的理解new列表中的页都是最为活跃的热点数据

LRU用来管理已经读取的页, 但当数据库刚启动时, LRU列表是空的, 即没有任何的页, 这时页都放在Free列表中.当须要从缓冲池中分页时,首先从Free列表中查找是否有可用的空闲页, 如有则将该页从Free列表中删除,放入到LRU列表中;不然,根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页

当页从LRU列表的old部分加入到new部分时, 称此时发生的操做为page made young

缓冲池中的页还可能被分配给自适应哈希索引, Lock信息, Insert Buffer等页,而这部分不须要LRU算法维护

InnoDB从1.0.x版本开始支持压缩页的功能, 16KB的页可被压缩为1KB, 2KB, 4KB, 8KB

在LRU中的页被修改后, 称该页为脏页(dirty page), 即缓冲池中的页和磁盘上的页数据产生了不一致. 这时数据库会经过CHECKPOINT机制将脏页刷新回磁盘, 而Flush列表中的页即为脏页列表, 脏页既存在于LRU列表中, 也存在与Flush列表中. LRU列表用于管理缓冲池中页的可用性, Flush列表用来管理将页刷新回磁盘,两者互不影响

3>重作日志缓冲

redo log buffer, InnoDB首先将重作日志信息先放入这个缓冲区, 而后按必定的频率将其刷新到重作日志文件. 通常状况下每一秒钟会将重作日志缓冲刷新到日志文件, 重作日志缓冲的默认大小为8MB

重作日志缓冲会在如下三种状况下被刷新到日志文件中:

  • Master Thread每一秒将重作日志缓冲刷新到重作日志文件
  • 每一个事务提交 时会将重作日志缓冲刷新奥重作日志文件
  • 当重作日志缓冲池剩余空间小于1/2时, 重作日志缓冲刷新到重作日志文件
4>额外的内存池

InnoDB对内存的管理 是经过一种称为内存堆(heap)的方式进行的, 在对一些数据结构自己的内存进行分配时, 须要从额外的内存池中进行申请, 当该区域的内存不够时,会从缓冲池中申请. 例如 : 分配了缓冲池, 可是每一个缓冲池中的帧缓冲还有对应的缓冲控制对象(记录了一些注入LRU,锁,等待等信息),这些内存须要从额外内存池中申请