ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

InnoDB体系架构与特性

2021-03-30 20:02:41  阅读:132  来源: 互联网

标签:缓存 架构 特性 索引 InnoDB IO 刷新 磁盘 脏页


InnoDB体系架构与特性,内存,缓冲池,LRU,插入缓存,两次写

InnoDB存储引擎体系架构

在这里插入图片描述

内存数据对象

在这里插入图片描述

后台线程

  1. Master Thread

    核心的后台线程,主要负责将缓存池中的数据异步刷新到磁盘,保证数据的一致性。(包括脏页刷新,合并缓存插入,UNDO页回收)

  2. IO Thread

    负责异步IO请求的回调处理。

  3. Purge Thread

    事务提交后,对应的undolog可能不再需要,该线程来回收已经使用并分配的undo页。

  4. Page Cleaner Thread

    在1.2.x版本引入,将脏页的刷新操作放到单独的线程中完成

内存

1.缓冲池

由于CPU速度与磁盘速度之间的鸿沟,基于磁盘的数据库系统通常使用缓冲池技术来提高性能。

数据库在读取页时,先判断缓存池中是否有,如果有就读取,没有就读取磁盘中的页,并放在缓存池中(称为FIX在缓冲池中)。

数据库在修改页时,先修改缓冲池中的页,再以一定的频率(Checkpoint机制)刷新到磁盘上。

2.LRU List 、Free List 、Flush List

  1. LRU List :Latest Recent Used,最近最少使用。

    传统的LRU算法就是将最频繁使用的页放在LRU列表的前端,最少使用的页放在末端,满了就淘汰末端的页。

    但是这种方法存在明显的问题,如果一个操作需要扫描很多页,甚至是全表扫描,就会将大量仅仅在本次操作中用到的冷门数据加入到LRU里,淘汰掉原本真正热门的数据。一个建好的LRU List就被破坏了。

    InnoDB存储引擎进行了优化,加入了midpoint位置(默认5/8),其上为new列表,其下为old列表。将新读取的页放在midpoint的下方old列表处。

    并且引入了一个innodb_old_blocks_time参数。扫描过程中,对数据页进行更新时判断,如果该页的最后一次查询时间减去第一次查询时间后超过了这个参数,就把这个页移入new列表(称为page made young)。这样一来,只查询一次或在短时间内查询多次的数据就不会进入new列表了。

  2. Free List

    数据库刚启动时,LRU列表是空的,没有任何页,页都存放在Free列表中。需要插入新的数据页时,就从Free List处拿。当Free List处被拿完了以后,就直接插入LRU List的midpoint处,淘汰末尾的页。

  3. Flush List

    该列表存放脏页(缓冲池与磁盘不一致的页)。同样,脏页也存在于LRU列表中。LRU列表管理缓冲池中页的可用性,Flush列表管理将页刷回磁盘。

3.重做日志缓存

重做日志会先放到这里,再以每秒钟一次的频率刷新到日志文件中,因此这块并不会很大。

Checkpoint技术

如果一个页一发生变化就马上刷新到磁盘,这样开销就太大了。

Checkpoint技术就是每隔一段时间,将缓冲池刷新到磁盘。有如下几个执行时机和目的:

  • Master Thread会以每秒或每十秒的速度执行checkpoint,这个过程是异步的。当数据库宕机时,并不需要根据重做日志来恢复所有数据,因为checkpoint之前的页都已经刷新回磁盘。称为Master Thread Checkpoint
  • 缓冲池中淘汰的页,如果是脏页,强制执行checkpoint,刷新到磁盘。称为FLUSH_LRU_LIST Checkpoint
  • 重做日志满了,强制checkpoint,使得一些重做日志失效,就可以把这些删掉了。称为Async/Sync Flush Checkpoint
  • 当脏页数目过多时(1.0.x之前默认为90%,之后为75%)。称为Dirty Page too much Checkpoint

Master Thread 工作方式

1.0.x版本之前

由多个循环组成:主循环(loop)、后台循环(background loop)、刷新循环(flush loop)、暂停循环(suspend loop)

主循环Loop分为每秒的操作和每十秒的操作

1.每秒一次的操作

  • 日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)

    因此,再大的事务提交时间也是很短的

  • 合并插入缓存(可能)

    如果当前IO压力小,就进行此操作

  • 至多刷新100个缓冲池里的脏页到磁盘(可能)

    即Dirty Page too much Checkpoint

  • 如果当前没有用户活动,则切换到background loop(可能)

2.每十秒的操作

  • 刷新100个脏页到磁盘(可能)

    过去10秒内的IO操作较少,就进行此操作

  • 合并至多五个插入缓存(总是)

  • 将日志缓冲刷新到磁盘(总是,与每秒的一样)

  • 删除无用的undo页(总是)

  • 刷新100个(如果脏页超过70%)或者10个脏页到磁盘(总是)

数据库空闲或关闭时,就会切换到background loop

  • 删除无用的undo页(总是)
  • 合并20个插入缓冲(总是)
  • 跳回到主循环(总是)
  • 不断刷新100个页直到符合条件(可能,跳转到flush loop中完成)

若flush loop中也没事做了,就会切换到suspend loop,将主线程挂起,等待事情的发生。

1.2.x版本之前

1.提供了innodb_io_capacity参数,来表示磁盘IO的吞吐量,默认200

用户可以根据当前环境来修改此参数,来提高数据库性能

  • 合并插入缓存的数量为innodb_io_capacity的20%
  • 刷新脏页的数据为innodb_io_capacity

2.将判断脏页的比例从90%改为75%

3.提供了innodb_adaptive_flushing(自适应刷新),通过判断产生重做日志(redo log)的速度来决定最合适的刷新脏页的数量。因此,有可能脏页比例小于75%时也会发生刷新

1.2.x版本

对于刷新脏页的操作,从主线程分离到一个单独的Page Cleaner Thread,从而减轻主线程的压力,同时进一步提高了系统的并发性

InnoDB关键特性

插入缓存

对于一个同时存在聚集索引和辅助索引的表来说,聚集索引叶子节点的插入是顺序的,不需要磁盘的随机读取,而辅助索引的叶子节点的插入是离散的,由于随机读取,导致了插入操作的性能下降

InnoDB存储引擎开创性的设计了Insert Buffer(数据结构是一棵B+树),对于非聚集索引的插入或更新,先判断插入的非聚集索引页是否在缓存池中,如果在就直接插入,如果不在就放到Insert Buffer 对象中。之后再以一定的频率和情况进行Insert Buffer和辅助索引叶子节点的merge(合并)操作。这时,通常能将在同一个索引页中的多个插入合并到一个操作中,从而提高效率。

有以下两个条件

  • 索引是辅助索引
  • 索引不是唯一的。(因为插入缓存并不会去判断记录的唯一性,否则又要去离散读,Insert Buffer就失去了意义)

在1.0.x版本引入了Change Buffer——Insert Buffer的升级,他们是Insert Buffer 、Delete Buffer 、Purge buffer,对应的操作是INSERT,DELETE,UPDATE。同样,适用于非唯一的辅助索引。

在以下几种情况下,Insert Buffer中的记录会merge(合并)到真正的辅助索引中

  • 辅助索引页被读取到缓存池中(通过查看Insert Buffer Bitmap页来确定是否需要merge)
  • Insert Buffer Bitmap页(用来标记该页的可用空间以及是否存在Insert Buffer中)追踪到该辅助索引页已无可用空间
  • Master Thread

两次写

Doublewrite两次写带来的是数据页的可靠性。

当数据库宕机时,可能正在将某个页写入表中,只写了一半。这种情况称为部分写失效。而重做日志中记录的是对页的物理操作,如偏移量800,写’aaa‘记录,如果页本身发生了损坏,在对其进行重做是没有意义的。也就是说在应用重做日志前,需要有一个页的副本。当写入失效发生时,先通过副本还原页,再进行重做。这就是两次写。

double write由两部分组成,一部分是内存中的double write buffer,另一部分是物理磁盘上共享表空间中连续的128页,即两个区。两部分大小均为2MB。在刷新脏页时,先将脏页复制到内存中的double write buffer,double write buffer再分两次,每次1MB顺序写入共享表空间的物理磁盘。然后再去同步磁盘。因为doublewrite页是连续的,是顺序写的,开销并不大。而将doublewrite buffer中的页写入各个表空间是离散的。

宕机后的恢复中,InnoDB存储引擎可以从共享表空间中的doublewrite中找到该页的一个副本,将其复制到表空间文件,再应用重做日志。
在这里插入图片描述

自适应哈希索引

自适应哈希索引(Adaptive Hash Index)简称AHI

InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引。

连续以相同的条件查询就会构造AHI

只能用来搜索等值查询,不能是范围查找。

异步IO

当前的数据库系统,包括InnoDB存储引擎,都采用异步IO(Asynchronous IO)

与之对应的是Sync IO

可以在一个IO请求发出后立即发下一个,而不需要一直等着

可以进行IO Merge,将多个IO合并成一个IO

刷新邻接页

当刷新一个脏页时,InnoDB存储引擎会检测该页所在的区的所有页,如果是脏页就一起刷新。

这样,通过AIO就可以将多个IO合并成一个IO

该工作机制在传统机械磁盘上有显著优势。对于固态硬盘,建议关闭此特性。

(可能将不怎么脏的页进行了写入,之后很快又变成了脏页)

标签:缓存,架构,特性,索引,InnoDB,IO,刷新,磁盘,脏页
来源: https://blog.csdn.net/rnhhhh/article/details/115333996

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有