InnoDB目前在各大互联网公司中广泛使用,其主要优点是支持事务处理(能处理复杂的业务场景)以及支持行级锁(支持高并发修改),能够提供高性能、高可用的存储服务。本文对《MySQL技术内幕——InnoDB存储引擎(第2版)》的第2章内容进行一个简要总结。
一、InnoDB体系架构
InnoDB有多个内存块(简称内存池),负责的工作有:维护线程/进程所需的内部数据结构、缓存磁盘数据、重做日志(redo log)缓冲等。简单说,内存池的功能就是缓存磁盘最近的数据(方便快速读取),以及处理数据库异常。
后台线程
1. Master Thread
核心后台线程,负责将内存池的数据异步刷新到磁盘,保证数据一致性。包括脏页刷新、合并缓冲等。
2. IO Thread
InnoDB大量使用了AIO(Async IO)来处理写IO请求,提高数据库性能。IO Thread负责的便是IO请求的回调。
3. Purge Thread
Purge Thread用来回收已经分配使用且不再需要的undo页,从1.1版本开始从Master Thread里独立出来。
4. Page Cleaner Thread
该Thread用来执行脏页刷新的操作,从1.2.x版本开始从Master Thread里独立出来。
内存
1. 缓冲池
InnoDB基于磁盘存储,为了提高性能,需要使用缓冲池。
读取:从缓冲池里读取,没有则回源磁盘,并保留一份至缓冲池;
写入:先修改缓冲池,再以一定的频率(Checkpoint机制)刷新到磁盘。
注:此缓冲思路可参考。一般缓冲的写入是直接写底层数据再更新(或删除)缓冲数据。
缓冲内容:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB存储的锁信息、数据字典信息(data dictionary)等。索引页和数据页占很大一部分。
可以有多个缓冲池实例,增加数据库并发能力。
2. LRU List、Free List和Flush List
LRU:Least recently used,最近最少使用,即使用较少的数据页(InnoDB缓冲池中页的默认大小16KB)放后面,最新及频繁使用的放前面。InnoDB做了优化,新读取的页放在midpoint位置,避免扫表等操作刷出热点数据,从而影响缓冲池的效率。
Free List:空闲列表页,初始存放页的地方,并逐步移入LRU列表中。
Flush List:LRU列表中页的数据被修改后(脏页),数据库通过checkpoint机制将脏页刷回磁盘,Flush列表即脏页列表。脏页既存在于LRU列表中,页存在于Flush列表中,两列表互不影响。
3. 重做日志缓冲
重做日志缓冲区,1s事务量大小即可,e.g. 8M。Master Thread每隔1s、事务提交、缓冲剩余大小小于1/2,三个时机会触发重做日志缓冲刷入重做日志文件中。
4. 额外的内存池
用来存储缓冲池等的一些元信息。
二、Checkpoint技术
缓冲池页内容变更时,需要同步磁盘,Checkpoint即为执行时机。需要解决的问题:
1.缩短数据库的恢复时间——宕机后只需要恢复Checkpoint后的数据;
2.缓冲池不够用时,将脏页刷新到磁盘;
3.重做日志不可用时,刷新脏页——重做日志是循环使用的,已经刷回磁盘的日志变可被覆盖;在被覆盖前,若重做日志还需要使用,就需要强制触发Checkpoint。
三、Master Thread工作方式
Master Thread内部由多个循环(loop)组成,主循环、后台循环、刷新循环、暂停循环等,Master Thread根据数据库状态在这之间切换。
每秒的操作:
1.日志缓冲刷新到磁盘,即使事务还没提交(总是)——因而事务commit时间很短;
2.合并插入缓冲(可能);
3.至多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能);
4.如果当前没有用户活动,则切换到后台循环(可能)。
每10秒的操作:
1.刷新100个脏页到磁盘(可能);
2.合并至多5个插入缓冲(总是);
3.将日志缓冲刷新到磁盘(总是);
4.删除无用的Undo页(总是);
5.刷新100个或10个脏页到磁盘(总是)。
后续的InnoDB版本对固定参数均有相关优化。
四、InnoDB关键特性
1.插入缓冲
插入缓冲和数据页一样,是物理页的一部分,不是缓冲池的一部分。主要用来辅助索引(非主键or唯一键)的写入,merge多个辅助索引的写入。
后续陆续引入了Delete Buffer和Purge Buffer。
实现:B+树。
2.两次写
解决的问题:数据库宕机引起的部分写失效。
doublewrite:在应用重做日志前,需要一个页的副本,当写入失效发生时,先通过副本还原该页,再进行重做。
3.自适应哈希索引
生产环境B+树高度一般为3-4层,故需要3~4次查询。
InnoDB自动根据访问频率和模式(查询条件),来为某些热点页建立哈希索引。
4.异步IO
异步,同时可以进行IO Merge操作。
5.刷新邻接页
可以合并AIO的多个IO写入。——建议传统机械硬盘启用此特性,固态硬盘有着高IOPS,可以不用。




