美文网首页
InnoDB体系架构

InnoDB体系架构

作者: hekirakuno | 来源:发表于2019-10-18 15:28 被阅读0次

innoDB有多个内存块,组成了一个大的内存池,负责维护所有进程/线程需要访问的多个内部数据结构;缓存磁盘上的数据;重做日志缓冲,等。后台线程(多线程)的主要作用是负责刷新内存池中的数据,保证缓存池中的内存韩村的是最近的数据,此外保障将已经修改的数据文件刷新到磁盘,同时保证在数据库发生异常时回复到正常状态。
后台线程:
master Thread
I/O Thread
Purge Thread


内存:
缓冲池:通过内存的速度来弥补磁盘速度较慢的影响。innoDB存储的最小单位是页(16k);对于数据库中页的修改,首先修改缓冲池中的页,然后以一定频率刷新到磁盘。(Checkpoint机制);缓冲池缓存的数据页类型为:索引页,数据页,undo页,插入缓冲,自适应哈希索引,锁,数据字典信息等。允许多缓冲池。
LRU FREE FLUSH
缓冲池通过LRU算法管理。但是做了优化,为了保障数据热点一直在最前面,所以新读取到的页不放在首部而是midpoint的位置,约为LRU列表的5/8处,然后经过一段时间后再加入LRU前端。
在数据库刚刚启动时,LRU列表为空,此时页都在FREE列表中,当需要从缓冲池分页时,首先从FREE列表中找到是否有可用的空闲页,然后删除,放入LRU,否则淘汰LRU最末尾的页,将该内存空间分给新的页。当页从old到new时,叫page mad young。
free+LRU!= buffer pool。因为缓冲池还有别的信息。
压缩页不是16k。

脏页:
当LRU列表被修改后,缓冲池中的页和 磁盘中的页数据不一致,称为脏页。此时checkpoint机制,将脏页刷回磁盘。
重做日志缓冲:
MT每一秒刷新到重做日志文件;事务提交;重做日志缓冲剩余空间小于1/2时;
额外内存池
对一些数据结构本身的内存也需要申请空间。


checkpoint
当事务提交时,先写重做日志,再修改页。他的目标是将缓冲池的脏页刷新到磁盘。只是什么时间,怎么刷,刷多少,是需要考虑的问题。
[如果重做日志可以无限增大,缓冲池可以缓存数据库所有数据,那么发生宕机时,可以恢复。但开销极大。]
checkpoint解决:
(1)缩短恢复时间;
(2)缓冲池不够用时,脏页刷新到磁盘;
(3)重做日志不可用时,刷新脏页;


Master Thread
loop:thread sleep实现。所以1/10秒一次都是不对的,可能会有延迟。
每秒一次的操作包括:日志缓冲刷入磁盘,即使事务没有提交。(总是)
合并插入缓冲,至多刷新100个innodb的缓冲池的脏页到磁盘,如果没活动切换到后台线程(可能)
每10秒一次的操作:
刷新100个脏页到磁盘(可能)
合并至多5个插入缓冲,日志缓冲刷入磁盘,删除无用undo页,刷新100个或10个脏页到磁盘(总是)
background loop
删除无用undo页,合并20个插入缓冲,跳回主循环(总是)
不断刷新100个页直到符合条件。(可能,跳转到flush loop完成)
flush loop
如果它当中没什么事情可以做了,那么切换到suspend loop 挂起MT


innoDB的关键特性:
插入缓冲,两次写,自适应hash索引,异步IO,刷新邻接页

插入缓冲
对于非聚集索引的插入或者更新操作,不合适每次都直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在则直接插入,若不在,则先放入到一个插入缓冲的对象中,然后再以一定的频率和情况进行插入缓冲与索引页子节点的merge操作,此时能将多个插入合并到一个操作中,就大大提高了非聚集索引插入的性能。
插入缓冲使用的条件:索引是辅助索引,索引并非唯一。
(如果要求唯一,那么还要去判断是否唯一,就会有离散读取情形,从而导致它失去了意义)
SHOW ENGINE INNODB STATUS
可以看记录,merges是实际IO的次数,会降低2/3左右。
后来新增了delete buffer ,purge buffer 原理与insert
一样。

insert / change buffer是一个b+树。merge的时机:
(1)辅助索引页被读取到缓冲池中时,
(2)bitmap页追踪到该辅助索引页已无可用空间时,
(3)Master Thread

两次写:
部分写失效:当正在写入某个页到表中,这个页只写了一部分,宕机。
【重做日志中记录的是对页的物理操作,如,偏移量800,写aaaa记录。但是如果页本身发生了损坏,那么在对其重做没有意义。也就是说,在重做日志之前,需要页的副本,当写入失效时,先通过副本还原该页,然后再进行重做。】
double write有两部分组成,一部分是内存中的 doublewrite buffer 2MB。一部分是物理磁盘上的共享表空间中的连续128个页,即两个区 2MB。在对于缓冲池的脏页进行刷新时,并不直接写入磁盘,而是通过memcpy函数将脏页先复制到内存中的doublewrite buffer上,之后通过它再分两次,每次1 mb,顺序写入共享表空间的物理磁盘,然后调用fsync函数,同步磁盘,避免缓冲写带来的问题。因为doublewrite页是连续的,所以开销不大。完成它的写入之后,再将它的页写入各个表的表空间文件中,此时写入是离散的。
如果写入时发生了崩溃,可以通过共享表空间获得一个副本,然后重做日志。

自适应hash索引
如果观察到建立hash索引可以提高速率,那么就会建立,所以是自适应的。使用的缓冲池的b+树建立;

异步IO
提高磁盘的操作性能。
对于(space ,page_no)为
(8,6),(8,7),(8,8)的页进行查询,AIO会判断他们是连续的,然后合并为一个IO,直接从(8,6)开始,读取48k的页。

刷新邻接页
刷新一个脏页时,它会检测该页所在区的所有页,如果是脏页则一起刷新。

(数据库真难……学习学习)

相关文章

网友评论

      本文标题:InnoDB体系架构

      本文链接:https://www.haomeiwen.com/subject/bxhimctx.html