InnoDB体系架构
体系架构简介
后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓冲的是最新的数据。此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生遗产的情况下InnoDB能恢复到正常运行情况
后台线程
1. Master Thread
非常核心的后台线程,主要讲缓冲池中的数据异步刷新到磁盘,保证数据的一致性、包括刷新脏页,合并插入缓冲、undo页的回收
2. IO Thread
InnoDB存储引擎中大量使用了AIO来处理写IO请求,IO Thread主要是负责这些IO请求的回调处理。
在InnoDB 1.0之前共有四个IO Thread,分别是write、read、insert buffer、log IO Thread
在Linux平台,IO Thread的数量不能进行调整,但是在Windows版本可以通过参数innodb_file_io_threads来增大IO Thread
从InnoDB 1.0.x开始,read Thread和write Thread分别增大到了4个,并且调整的参数也变成了innodb_read_io_threads和innodb_write_io_threads来进行线程数量设置
3. Purge Thread
事务被提交之后,它对应的undolog就可能不再需要了,因此需要PurgeThread来进行回收已经适用并且分配的undo页,在InnoDB 1.1版本之前,purge操作都是在Master Thread中进行,但是在1.1版本之后,这个操作到了单独的线程Purge Thread中进行,可以手动打开,而到了1.2版本,支持多个Purge Thread,可以手动进行设置个数
4. Page Cleaner Thread
1.2版本之后引进的,作用是将之前的刷新操作都放入单独的线程中完成,减轻Master Thread的工作已经对于用户查询县城的阻塞,提高性能
内存
1. 缓冲池
InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理,因此也可以将其视为基于磁盘的数据库系统,而基于磁盘的数据库系统通常使用缓冲池技术来提高数据库的整体性能
页通过一种被称为CheckPoint的机制刷新脏页回磁盘
缓冲池中缓冲的数据页类型有:索引页、数据页、undo页、插入缓冲、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等。不能简单地认为,缓冲池只是缓冲索引页和数据页,他们只是占缓冲池很大的一部分。
1.0版本开始,允许有多个缓冲池实例,减少资源竞争,增加并发处理能力,由innodb_buffer_poll_instances参数控制
2.LRU List、Free List和Flush List
InnoDB存储引擎中,缓冲池中的页默认大小为16KB,使用改进后的LRU算法对缓冲池进行管理
改进的LRU算法
在LRU列表中加入了midpoint位置,新读取到的页放在midpoint,我们将midpoint之前的称为new列表,之后的称为old列表,读取到mid位置后的页经过innodb_old_blocks_time之后加入到热端。
主要目的是防止快速扫描多表时,将整个热点数据页全部刷出去
从1.0版本开始,InnoDB支持压缩页功能,可以将16kb压缩到1kb、2kb、4kb、8kb
LRU列表用来管理已经读取的页,而未读取的页则存放在FREE列表中
在LRU列表中的页被修改之后,与磁盘上的数据产生了不一致,则为脏页,将脏页通过checkpoint机制刷新回磁盘
Flush List中存储脏页,脏页既在LRU列表中,也在Flush列表中,分别管理可用性和刷新回磁盘,互不影响
重做日志缓冲(redo log buffer)
InnoDB存储引擎先将日志信息先放到这个缓冲区,然后按一定频率刷新到重做日志文件
额外的内存池
InnoDB存储引擎对内存的管理是通过一种称为内存堆的方式进行的。对数据结构本身的内存进行分配的时候,需要从额外的内存池中进行申请
Checkpoint技术
Write Ahead Log策略,当事务提交时,先写重做日志,再修改页。
当数据库发生宕机时,只需要对于checkpoint之后的重做日志进行恢复
当缓冲池不够用时,将LRU中溢出的页刷回磁盘中
Master Thread工作方式
InnoDB的主要工作都是在Master Thread中完成的
Master Thread具有最高的线程优先级别,由多个循环组成,主循环、后台循环、刷新循环、暂停循环
- 主循环分为1s/次和10s/次
- 1s/次必做的事情:将日志缓冲刷新到磁盘;可做的事情:合并插入缓冲、刷新最多100脏页到磁盘、没有用户活动则切换到后台循环
- 10s/次必做的事情:合并最多5个插入缓冲、刷新日志缓冲、删除无用undo页、刷新脏页到磁盘
- 后台循环
若当前没有用户活动或者数据库关闭,就会切换到这个循环,主要删除无用的undo页、合并插入缓冲、跳回主循环 - 刷新循环
后台循环进入刷新循环刷新等待脏页率较高的100个页出现 - 暂停循环
如果刷新循环也无事可做,那么就直接进入暂停循环挂起
InnoDB关键特性
1.插入缓冲
由于费聚集索引对应数据页的离散性,导致普通索引的插入操作的性能下降,因为普通索引的插入不是顺序的,而是乱序的。
InnoDB设计了insert buffer,对于费聚集索引的插入或者更新,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在,则直接插入,则放入到insert buffer对象中,以一定频率进行insert buffer和辅助索引子节点的merge操作,这时通常能将多个插入合并到一个操作中,大大提高了性能
使用insert buffer有两个条件,索引必须是普通且非唯一的索引,非主键很容易理解,至于唯一就是因为唯一的情况下需要进行哈希判断,失去了提高性能的意义
不仅如此,1.0.x版本之后,还引入了change buffer,是insert buffer的升级版
insert buffer的实现是B+树
2.两次写
两次写有两部分组成,一部分是doublewrite buffer,当对缓冲池的脏页进行刷新时,会将数据页先复制到doublewrite buffer中,然后写入磁盘中的共享表空间存储副本,再写入表空间文件中,如果发生表文件损坏,可以直接用副本恢复
3.自适应哈希索引
存储引擎会根据观察到的情况来决定要不要建立哈希索引来提升速度
4.异步IO
AIO的两个优势:
- 不需要等待前一个IO操作结束就可以继续
- 可以进行IO merge操作,也就是将多个IO合并为1个IO
5.刷新邻接页
工作原理:当刷新一个脏页时,InnoDB存储引擎会检测该页所在区的所有页,如果也是脏页,那么久一起刷新
启动、关闭与恢复
介绍参数innodb_fast_shutdown
- 取值为0时,MySQL数据库需要完成所有的full purge和merge insert buffer,并且刷新脏页
- 取值为1时,MySQL数据库不会完成full purge和merge insert buffer操作,但是还是会刷新脏页
- 取值为2时,MySQL数据库啥也不干,只将日志写入日志文件,下次启动时进行恢复