InnoDB引擎简介
第二章 InnoDB引擎
目录- 第二章 InnoDB引擎
- 2.1 体系架构
- 2.1.1 后台线程
- 1. Master Thread
- 2. IO Thread
- 3. Purge Thread
- 4. Page Cleaner Thread
- 2.1.2 内存
- 1. 缓冲池
- 2. LRU List、Free List、Flush List
- 3. 重做日志缓存 Redo Log Buffer
- 4. 额外的内存池
- 2.1.1 后台线程
- 2.2 Checkpoint技术
- 2.3 Master Thread工作方式
- 1. 1.0.X之前的版本
- 2. 1.2.x版本
- 2.4 InnoDB关键特性
- 2.4.1 插入缓存
- 1. Insert Buffer
- 2. Change Buffer
- 3. Insert Buffer的内部实现
- 4. Merge Insert Buffer
- 2.4.2 双写
- 2.4.3 自适应哈希索引
- 2.4.4 异步IO
- 2.4.5 刷新邻接页
- 2.4.1 插入缓存
- 2.5 启动、关闭与恢复
- 2.3 Master Thread工作方式
- 2.1 体系架构
2.1 体系架构
后台线程主要作业是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。另外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下InnoDB能恢复到正常运行状态。
2.1.1 后台线程
InnoDB存储引擎是多线程的模型,因此后台由多个不同的后台线程,负责处理不同的任务。
1. Master Thread
主要负责将缓存池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新,合并插入缓冲等。
2. IO Thread
引擎使用了大量AIO(Async IO)来处理IO请求,IO Thread负责请求的回调处理。
一个 insert buffer thread, 一个log thread,四个读,四个写
3. Purge Thread
事务被提交后,所使用的undolog不再需要,被Purge Thread回收。
4. Page Cleaner Thread
将之前版本中的脏页刷新操作都放到单独的线程中来完成。
2.1.2 内存
1. 缓冲池
简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库的性能影响。
? 在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为把页”fix“在缓冲池中。
修改则是,先修改缓冲池中的页,再以一定的频率刷新到磁盘中,通过Checkpoint的机制刷新回磁盘。
2. LRU List、Free List、Flush List
新读取到的页不是直接放在LRU列表首部,而是放在Midpoint位置
Free List用来存放空的页,需要使用一张新的页时,从Free列表中删除,否则会淘汰LRU列表中末尾的页
Buffer pool hit rate表示命中率,不应该低于95%,如果低于需要观察是否由于全表扫描引起的LRU列表被污染
在LRU列表中的页被修改了之后,称做脏页,即缓存池中的页和磁盘上的页数据不一致。
Flush列表即为脏页列表,是同时存在的关系
3. 重做日志缓存 Redo Log Buffer
先将重做日志信息放入这个缓存区,然后按照一定频率将其刷新到重做日志文件
以下三种情况会刷新到外部磁盘的重做日志文件中
- Master Thread 每一秒将buffer刷新到日志文件
- 每个事务提交时会刷新
- buffer剩余空间小于1/2时
4. 额外的内存池
堆内存的管理是通过内存堆进行的
2.2 Checkpoint技术
为了避免数据发生丢失,当前事务数据库系统都是Write Ahead Log策略,即当事务提交时,先写重做日志,再修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成数据的恢复。
Checkpoint解决以下问题:
- 缩短数据库的恢复时间(如果很久没有刷新磁盘,宕机了之后需要恢复很久)
- 缓冲池不够用时,将脏页刷新到磁盘(LRU溢出的页如果是脏页,强制执行Checkpoint)
- 重做日志不可用时,刷新脏页
Checkpoint类型:Sharp Checkpoint、Fuzzy Checkpoint
第一种发生在数据库关闭时将所有的脏页刷新到磁盘上,默认工作方式。
第二种只刷新一部分脏页,从而不影响数据库性能,而Fuzzy又分很多种
Fuzzy Checkpoint:
- Master Thread,每秒或每十秒的速度从脏页列表种刷新到磁盘。过程是异步的
- FLUSH_LRU_LIST
- Async/Sync Flush,指的redo log不可用的情况
- Dirty Page Too Much,一般Buffer Pool中75%都是脏页时会刷新
2.3 Master Thread工作方式
InnoDB存储引擎的主要工作都是在一个单独的后台线程完成的
1. 1.0.X之前的版本
即使某个事务还没有提交,仍然会每秒将redo log buffer刷新到redo log中,也可以很好解释为什么再大的事务提交的时间也很短暂
2. 1.2.x版本
对于刷新脏页的操作,从Master Thread线程分离到一个单独的Page Cleaner Thread
2.4 InnoDB关键特性
包括:
- 插入缓存 Insert Buffer
- 双写 Double Write
- 自适应哈希索引 Adaptive Hash Index
- 异步I/O Async I/O
- 刷新邻近页 Flush Neighbor Page
2.4.1 插入缓存
1. Insert Buffer
和数据页一样,也是物理页的一个组成部分。
对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页,而是先判断插入的非聚集索引页在不在缓冲池中,如果在,直接插入;如果不在,先插入到 Insert Buffer对象中。然后再以一定频率进行Insert Buffer和辅助索引页子节点的merge操作。
需要同时满足索引是辅助索引,索引不是唯一的。
2. Change Buffer
3. Insert Buffer的内部实现
4. Merge Insert Buffer
2.4.2 双写
首先存在一个页的副本,当写入发生失效时,先通过页的副本来还原该页,再进行重写,这就是Double Write。由两部分组成,一部分是内存中的doublewrite buffer,2MB,另一部分是物理磁盘上共享表空间中连续的128个页,即2个区,也是2MB.
操作如下:
-
对缓冲池的脏页进行刷新时,并不直接写磁盘,通过memcpy函数将脏页复制到内存中的 doublewrite buffer。
-
之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘。
-
这个过程中,双写是连续的,因此这个过程是顺序写入。完成双写页的写入后,再将doublewrite buffer中的页写入各个表空间文件中,此时写则是离散的
2.4.3 自适应哈希索引
引擎会监控对表上各索引页的查询。如果观察到简历哈希索引可以带来速度提升,则建立,这称为自适应哈希索引。
2.4.4 异步IO
同步IO即每进行一次IO操作,需要等待此次操作结束才能继续接下来的操作。
异步与同步的区别:
用户发出一条索引扫描的查询,可能要扫描多个索引页,需要进行多次的IO操作。
同步则会再每扫描一个页并等待其完成后再进行下一次的扫描。
异步再发出一个IO请求后立即再发出另一个IO请求,当全部的IO请求发送完毕后,等待所有的IO操作完成。
异步IO的另一个优势是 IO merge,将多个IO合并成一个IO。发送(8,6)(8,7)(8,8),同步IO需要三次,异步IO只用一次。
2.4.5 刷新邻接页
当刷新一个脏页时,引擎会检测该页所在的区,如果是脏页,那么一起进行刷新。
这样可以通过AIO将多个IO写入操作合并为一个IO
2.5 启动、关闭与恢复
innodb_fast_shutdown 默认为1
0表示:关闭时,完成所有的full purge和merge insert buffer还有脏页的刷新
1表示:不进行上述的刷新,但是buffer pool中的一些脏页会刷新到磁盘
3表示:将日志都写入日志文件,下次启动时进行recovery
innodb_force_recovery 可以设置6个参数 1~6
3是不进行回滚