InnoDB是MySQL5.5之后默认支持的表存储引擎。
其特点是:行锁设计,支持MVVC,支持外键,提供一致性非锁定读。
InnoDB存储引擎有多个内存块,负责一下工作:
维护有所进程和线程需要访问的多个内部数据结构
缓存磁盘上的数据,方便快速地读取,同时在对磁盘文件的数据修改之前在这里缓存
重做日志缓冲。
后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓冲的是最新的数据。此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下InnoDB能恢复到正常水平。
后台线程:
Master Thread:核心后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲、UNDO页的回收等
IO Thread:对来IO请求进行处理,提高数据库的性能。主要负责IO请求的回调,有四种:write,read,insert buffer,log IO thread。
Purge Thread:事物提交后,其所使用的undolog可能不再被需要,所以要进行回收已经使用并且分配的undo页。在1.1之前purge操作需要依赖Master Thread进行完成,之后的版本可以自己进行处理,独自使用一个线程。
Page Cleaner Thread:在1.2版本之后引入的,其作用是将之前版本的脏页的刷新操作都放入到单独的线程中来完成,而其目的是为了减轻原Master Thread 带来的工作和对于用户查询线程的堵塞。
内存:
缓冲池:存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理,因此可将其视为基于磁盘的数据库系统。
缓存其实的意义是通过内存数据来弥补硬盘速度。在数据库中进行读取页的操作,首先将磁盘读到的页存放到缓冲区中,这个过程称之为FIX过程,下次再次读取页的时候可以先查询缓冲区有没有对应的页,如果没有的话再进入磁盘中进行读取。
对于修改操作,也是先修改缓冲区中的页,然后把页再按照一定频率刷新到磁盘中去,具体操作是通过checkpoint的机制刷新回磁盘。
缓冲池中缓存的数据页类型有:
LRU List、Free List、Flush List:
数据库中的缓冲池是通过LRU(最近最少使用)算法进行管理的,即最频繁使用的页在LRU列表的前段,而最少使用的也在LRU页的尾端。当缓冲池不能存放读取到页的时,将首先释放LRU列表中尾端的页。
在InnoDB存储引擎中,缓冲池中页的大小默认大小为16kb,同样使用LRU算法对缓存池进行管理。从磁盘中新读取到的页会放入LRU列表的midpoint位置。在这个位置之前的都是最活跃的热点数据,之后都是old数据。(midpoint是因为有些操作例如索引或者数据的扫描需要访问到表中许多页这些页面并不是确实需要的,可能会将真正的热点数据页进行后退,最后被移除)
LRU列表用来管理已经读取到的页,当数据库刚刚启动的时候,这个LRU列表是空的,这时候的页都放置在Free List中,当需要从缓冲区进行分页的时候,首先从Free List中进行查询是否有空白页,若有空白则从Free List中删除这个页放入到LRU List中
从1.0版本之后开始支持压缩页的功能,原来16kb的可以压缩到1,2,4,8kb。对于非16kb的页面是通过unzip_LRU列表进行管理的,unzip_LRU列表对不同的压缩页大小的页进行管理:
检查是否有4kb的页,有就分配
没有就检查8kb,有8kb的就是分成2个4kb
没有8kb就申请16kb的,分成2个4kb,1个8kb。
额外的内存池:
对内存的管理是通过一种称为内存堆的方式进行的,在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当不够时候,会从缓冲池中进行申请。但是每个缓冲池中的帧缓冲还有对应的缓冲控制对象,这些对象记录了一些诸如LRU、锁、等待等信息。
Checkpoint技术:
缓冲池的目的是为了提高CPU速度与磁盘速度的鸿沟,所有表的操作都是最先在缓冲池中完成。如果有一条DML语句改变了一个表中的记录,那么这个过程中的页其实是脏的,数据库需要将最新版本的也从缓冲池刷新到磁盘。
如果每一次改变都要进行提交,那么开销会很大,所以一般会使用一种Write Ahead Log策略,当事物提交的时候,先写日志再进行修改。日志可以帮助进行数据的恢复。
checkpoint技术主要是为了解决以下几个问题:
缩短数据库的恢复时间
缓冲池不够用时,将脏页刷新到磁盘
重做日志不可用时,刷新脏页
此外,当数据库缓冲池不够用,根据LRU算法会移除一些不常用的页,若此时的页为脏页则需要强制执行checkpoint。
在这本书中作者把checkpoint分成了两种,Sharp Checkpoint和Fuzzy Checkpoint
Sharp Checkpoint指:在数据库关闭的时候将所有的脏页进行刷新
Fuzzy Checkpoint指:在数据库运行时候刷新,但是只刷新一部分的脏页
具体的Fuzzy Checkpoint可以分成4种:
Master Thread CheckPoint,在Master Thread的过程中发生,以1~10s的速度从缓冲池中的脏页进行刷新回磁盘,而且这个是异步的操作。
FLUSH_LRU_LIST Checkpoint InnoDB引擎需要差不多100个空白页进行使用(这是前提),进行操作之前需要检查(TM的1.1X之前),如果没有100个空白页就需要进行对后面的一部分脏页进行CheckPoint,这就是 FLUSH_LRU_LIST Checkpoint
Async/Sync Flush CheckPoint 是重做日志中不可用的情况,这时需要强制将一些页刷新回磁盘。这时候的脏页是从脏页列表中选取的,若将已经写入到重写日志中带LSN标记为redo_lsn。
最后一种情况Dirty Page too much看名字就知道了,太多的脏页进行了刷新。
Master Thread工作方式
1.0.X之间的Master Thread
是最高线程优先级别,内部由多个循环组成:主键环、后台循环、刷新循环、暂停循环。Master Thread会根据情况进行切换。
主循环是通过thread sleep来实现,这意味着每秒一次或者每10秒一次的操作其实是不准确的。在负载很大的情况下回有延迟,只能说大概在这个频率下。
每一秒的操作包括:日志缓冲刷新到磁盘,即使这个事务还没有提交。合并插入缓冲。至多刷新100个InnoDB的缓冲池中的脏页到磁盘。如果没有用户活动,切换到background loop
即使没有事务提交,引擎依然会重做日志的缓冲,将内容刷新到重做日志。
合并插入缓冲不是每一次都发生会先去判断,前1秒的IO操作数据,如果小于5次就会发生,因为它认为当前是适合进行合并插入的。
InnoDB关键特性
插入缓冲、两次写、自适应hash索引、异步IO、刷新相邻页