InnoDB是事务安全的MySQL存储引擎,设计上采用了相似于Oracel数据库的架构。一般来讲,InnoDB存储引擎是OLTP应用中核心表的首选存储引擎。同时,也正是由于InnoDB的存在,才使MySQL数据库变得更有魅力。本文将介绍InnoDB存储引擎的体系架构及其不一样于其余存储引擎的特性。算法
该引擎是第一个完整支持ACID事务的MySQL引擎,其特色是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,同时被设计用来最有效的利用以及使用内存和CPU。数据库
从下图可见,InnoDB存储引擎有多个内存块,能够认为这些内存块组成了一个大的内存池,负责以下工做:缓存
InnoDB存储引擎是多线程的模型,所以气候态有多个不一样的后台线程,负责处理不一样的任务。安全
1.Master Thread
Master Thread是很是核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲、UNDO页的回收等。
2.IO Thread
在InnoDB存储引擎中大量使用了AIO(Async IO)来处理写IO请求,这样能够极大提升数据库的性能。而IO Thread的工做主要是负责这些IO请求的回调(call back)处理。
3.Purge Thread
事务被提交后,其所使用的undolog可能再也不须要,所以须要PurgeThread来回收已经使用并分配的undo页。
4.Page Cleaner Thread
将脏页的刷新操做都放入到单独的线程中来完成。而七亩地是为了减轻原master Thread的工做及对于用户查询线程的阻塞,进一步提升InnoDb存储引擎的性能。数据结构
一、缓冲池
InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。所以可将其视为基于磁盘的数据库系统。在数据库系统中,因为CPU速度与磁盘速度之间的鸿沟,基于磁盘的数据库系统一般使用缓冲池技术来提升数据库的总体性能。多线程
缓冲池简单来讲就是一块内存区域,经过内存的速度来弥补磁盘速度较慢对数据库性能的影响。在数据库中进行读取页的操做,首先将从磁盘读到的页放在缓冲池中,这个过程称为将页“FIX”在缓冲池中。下一次再读取相同的页时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。不然,读取磁盘上的页。架构
对于数据库中页的修改操做,则首先修改在缓冲池中的页,而后再以必定的频率刷新到磁盘上。须要注意的是,页从缓冲池刷新回磁盘的操做并非在每次页发生更新时触发,而是经过一种称为Checkpoint的机制刷新回磁盘。一样,这也是为了提升数据库总体性能。异步
综上所述,缓冲池大小直接影响着数据库的总体性能。性能
二、LRU List
这段主要介绍InnoDB存储引擎怎么对缓冲池进行内存管理的。优化
在InnoDB存储引擎中一样适用LRU算法对缓冲池进行管理。稍有不一样的是InnoDB存储引擎对传统的LRU算法作了一些优化在InnoDB的存储引擎中,LRU列表还加入了midpoint位置。新读取到的页,虽然是最新访问的页,但并非直接放入到LRU列表的首部,而是放入到LRU列表的mindpoint位置。这个算法在InnoDB存储引擎下被称为mindpoint insertion strategy。在默认配置下,该位置在LRU列表长度的5/8处。
三、重作日志缓冲
InnoDB存储引擎的内存区除了有缓冲区外,还有重作日志缓冲。InnoDB存储引擎首先将重作日志信息放入到这个缓冲区,而后按必定平率将其刷新到重作日志文件。重作日志缓冲通常不须要设置得很大,由于通常状况下每一秒会将重作日志缓冲刷新到日志文件,所以用户只需保证每秒产生的事务量在这个缓冲大小以内便可。
四、额外的内存池
在对一些数据结构自己进行内存分配时,须要从额外的内存池中进行申请,当该区域的内存不够使,会从缓冲池中进行申请。
前面已经讲到了,缓冲池的设计目的为了协调CPU与磁盘速度的鸿沟。所以页的操做首先都是在缓冲池中完成的。若是一条DML(数据操做语言)语句,如Update或Delete改变了页中的记录,那么此时页时脏的,即缓冲池中页的版本要比磁盘的新。数据库须要将新的版本的页从缓冲池刷新到磁盘。
假若每一次一个页发生变化,就将新页的版本刷新到磁盘,那么这个开销是很是大的。若热点数据集中在某几个页中,那么数据库的性能将变得很是差。同时,若是在从缓冲池将页的新版本刷新到磁盘时发生宕机,那么数据就不能恢复了。为了不发生数据丢失的问题,当前事务数据库系统广泛都采用Write Ahead Log策略,即当事务提交时,先写重作日志,再修改页。当因为发生宕机而致使数据丢失时,经过重作日志来完成数据的恢复。这也是事务ACID中D(Durability持久性)的要求。
Checkpoint(检查点)技术的目的是解决如下几个问题:
当数据库发生宕机时,数据库不须要重作全部的日志,由于Checkpoint以前的页都已经刷新回磁盘。故数据库只需对Checkpoint后的重作日志进行恢复。这样就大大缩短了恢复时间。
此外,当缓冲池不够用时,根据LRU算法会溢出最近最少使用的页,此页即为脏页,那么须要强制执行Checkpoint,将脏页也就是页的最新版本刷新回磁盘。
在InnoDB存储引擎中,Checkpoint发生的时间、条件及脏页的选择等都很是复杂。而Checkpoint所作的事情无外乎是将缓冲池中的脏页刷回到磁盘。不一样之处在于每次刷新多少页到磁盘,每次从哪里取脏页,以及什么时间触发Checkpoint。在InnoDB存储引擎内部,有两种Checkpoint,分别为:
但如果数据库在运行时也是用Sharp Checkpoint,那么数据的可用性就会受到很大的影响。故在InnoDB存储引擎内部使用Fuzzy Checkpoint进行页的刷新,即只刷新一部分脏页,而不是刷新全部的脏页。