InnoDB体系架构

来源:互联网 发布:mac flash发热 编辑:程序博客网 时间:2024/06/06 20:06

InnoDB体系架构

1.多个后台线程:负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据;负责将已修改的数据文件刷新到磁盘文件。
2.innodb储存引擎内存池:缓存磁盘上的数据(将磁盘中的页读取到内存中),方便快速读取,同时在对磁盘文件的数据修改之前进行缓存。(缓冲池:数据页、索引页、插入缓冲、锁信息、自适应哈希索引、数据字典信息;重做日志缓存;额外内存池)


1.InnoDB存储引擎是多线程模型

  1. master thread:主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页刷新、合并插入缓冲(insert buffer)、undo页的回收等(后面版本会将某些处理交给其他线程实现)
  2. IO thread:innodb中大量使用AIO(async IO)来处理写IO请求;而IO thread主要负责这些IO请求的回调处理(1.0版本有write thread、read thread、insert buffer thread、log thread)(用户可以在发出一个IO请求后立即再发出另一个IO请求,当全部IO请求发送完毕后,等待所有IO操作完成,就是AIO)
  3. Purge thread:存储引擎会执行full purge操作,即删除无用的undo页,存储引擎会判断当前事务系统中已被删除的行是否可以真正删除(事务提交后不能马上删除undo log和undo log所在的页。
    存储引擎会:1.将undo log放入列表中,以供purge操作;2.判断undo log是否可以重用,若可以分配给下个事务使用。
    个人理解:应该是根据当前数据库实例中还有没有比给行的删除标记的事务版本号小的事务存在。若有,则不能purge,继续重用;若没有,则可以purge)由于存放undo log的列表是以记录进行组织的,而undo页可能存放着不同事务的undo log,因此purge操作需要涉及磁盘的离散读取操作
    1.1版本前purge操作仅在master thread中完成,1.1后purge操作可以独立到单独的线程中进行,减轻master thread的压力
  4. Page Cleaner thread:负责脏页的刷新操作
    1.2版本前刷新操作是有master thread负责的

什么是合并插入缓冲?
对于非聚集索引当插入或更新操作,不是每一次都直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在,则直接插入;否则,先存放到一个insert buffer对象(B+Tree)中,然后按照一定的频率和情况进行insert buffer和辅助索引页节点的merge操作(通常能够把对同一个索引页中的插入更新操作合并起来进行,然后把该辅助索引页读到内存中,再将记录插入到该页)提高插入性能。(存储引擎会判断当前一秒内发生的IO次数是否小于5次,若小于5次,则认为当前的IO压力很小,可以执行合并插入缓冲的操作)
为什么会有合并插入缓冲?
一般情况下,当主键为auto increment时插入操作,数据页的存放是按主键进行顺序存放的,但对于非聚集索引页叶子节点的插入不再是顺序的,这时就需要离散地访问非聚集索引页,随机读取导致插入操作性能下降。
Insert Buffer的使用需要满足2个条件:索引是辅助索引;索引不是唯一(unique)。
为什么是不唯一的?
因为如果是唯一索引,合并时可能会出现冲突,造成插入失败


2.内存

  1. 缓冲池:页从缓冲池刷新会磁盘的操作并不是在每次页发生更新时触发,而是通过checkpoint机制刷新回磁盘。从InnoDB1.0.x版本开始允许有多个缓冲池实例。每个页根据哈希值平均分配到不同缓冲池实例中。好处是可以减少数据库内部资源竞争,增加数据库的并发处理能力
  2. LRU List、Free List、Flush List
    LRU List:
    缓冲池通过LRU算法进行内存管理。最频繁使用的页在LRU列表的前端,最少使用的页在尾端,当缓冲池不能存放新读取的页时,会释放尾端的页,被删除的页如果是脏页,需要强制执行checkpoint,而新加入的页会放在midpoint位置(默认在LRU列表的5/8处)midpoint之前的列表称为new列表,之后的称为old列表
    old列表页加入new列表的操作称为page made young(innodb_old_time的参数设置可能导致页无法移动到new列表,称为page not made young)这部分没有继续了解
    Free List:
    数据库刚启动时,LRU列表是空的,这时系统分配给存储引擎的内存页放在free列表中,当需要从缓冲池中分页时,先从free列表中获取空闲页,并将该页从free列表删除放入LRU列表
    Flush List:
    在LRU列表中的页被修改后,称该页为脏页,即缓冲池中的页和磁盘上的页的数据产生了不一致。而Flush列表中的页即为脏页列表。注意,脏页既存在于LRU列表,也存在于Flush列表。LRU列表用来管理缓存池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者这互不干扰。
  3. 重做日志缓冲
    存储引擎先将重做日志信息放入到这个缓冲区,然后按一定频率将其刷新到重做日志文件
    三种情况:
    1.事务提交前需要把redo log buffer的内容写到redo log
    2.master thread每一秒刷新一次
    3.当重做日志缓冲池剩余空间小于1/2
  4. 额外的内存池

CheckPoint技术

sharp checkpoint:发生在数据库关闭时将所有的脏页刷新回磁盘;
fuzzy checkpoint:包括master thread checkpoint、FLUSH_LRU_LIST checkpoint、Async/Sync Flush checkpoint、Dirty Page too much checkpoint
1.master thread checkpoint:master thread按一定频率异步将缓冲池中的脏页列表中刷新一定比例的页回磁盘

2.FLUSH_LRU_LIST checkpoint:保证LRU列表中有差不多100个空闲页可供使用(MySQL5.6版本开始检查LRU列表可用空间的任务放在Page Cleaner Thread中进行)

3.Async/Sync Flush checkpoint:在重做日志文件不可用时,需要强制将一些脏页刷新回磁盘(此时的脏页是Flush List中选取的),保证重做日志的循环使用的可用性。(Page Cleaner Thread负责)
将已经写入到重做日志的记为redo_lsn,已经刷新回磁盘的记为checkpoint_lsn(log sequence number)
定义checkpoint_age = redo_lsn - checkpoint_lsn
async_water_mark = 75% * total_redo_log_file_size
sync_water_mark = 90% * total_redo_log_file_size
当checkpoint_age < async_water_mark,不需要刷新任何脏页到磁盘
当async_water_mark < checkpoint_age < sync_water_mark,触发Async Flush,从flush列表中刷新足够的脏页回磁盘,使得刷新后满足checkpoint_age < async_water_mark
checkpoint_age > sync_water_mark(一般很少发生,除非设置的重做日志文件太小,并且进行类似LOAD DATA的BULK INSERT操作)此时触发Sync Flush操作,从Flush列表中刷新足够的脏页回磁盘,使得刷新后满足checkpoint_age < async_water_mark

4.Dirty Page too much checkpoint:当脏页的数量太多时存储引擎回强制进行checkpoint

原创粉丝点击