MySQL之InnoDB

       InnoDB 存储引擎是 OLTP(联机事务处理系统) 应用中核心表地首选存储引擎。

1. 体系结构

在这里插入图片描述

1.1 后台线程

       InnoDB 是多线程模型,其后台有多个不同的后台线程,负责处理不同的任务。

1.1.1 Master Thread

       主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲(Insert Buffer)、Undo 页的回收等。

1.1.2 IO Thread0

       InnoDB 大量使用了 AIO(异步IO)来处理写IO请求,IO Thread 的工作主要是负责这些 IO 请求的回调处理。

1.1.3 Purge Thread

       事务被提交后,其所使用的undo log可能不再需要,因此需要 PurgeThread 来回收已经使用并分配的 undo 页。

       undo logInnoDB MVCC事务特性的重要组成部分,当我们对记录做了变更操作时就会产生undo记录,undoo记录默认被记录到系统表空间。

1.1.4 Page Cleaner Thread

       其作用是脏页的刷新操作都放入到单独的线程中来完成。目的是减轻 Master Thread 的工作以及对于用户查询的阻塞。

1.2 内存

1.2.1 缓冲池

       InnoDB是基于磁盘存储的,并将其中的记录按照页的方式进行管理。CPU与磁盘速度有几个数量级的差距,而缓冲池技术则是用来弥补差距。

       缓冲池的工作原理如下

       在数据库进行读取页的操作时,首先将磁盘读到页放在缓冲池中。下一次在读相同的页时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。

       在数据库进行修改页的操作时,首先修改缓冲池中的页,然后再以一定频率刷新到磁盘上。页从缓冲池刷新会磁盘的操作并不是在每次页发生更新时触发,而是通过一种CheckPoint的机制刷新回磁盘。

       缓冲池的数据页类型

       索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)InnoDB存储的锁信息(lock info)、数据字典信息(data dictionary)等

1.2.2 LRU List、Free List 和 Flush List

       数据库中的缓冲池是通过LRU算法进行管理的,即最频繁使用的页也在LRU列表的前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读取到的页时,将首先释放LRU列表中尾端的页。

       InnoDB中,LRU列表中还加入了midpoint位置。新访问的页并不是直接放到LRU列表的首部,而是放到LRU列表的midpoint位置。这样做的原因是某些SQL可能会导致将不活跃的数据刷入,而活跃被完全刷出。

       LRU列表用来管理已经读取的页,数据库刚启动时,LRU列表是空的,即没有任何的页。此时页都存放在Free列表中查看是否有可用的空闲页,若有则将该页从Free列表中删除,放入到LRU列表中。

       LRU列表中的页被修改后,称该页为脏页,即缓冲池中的页或磁盘上的页的数据产生了不一致。Flush列表中的页即为脏页列表,脏页即存在于LRU列表中,也存在与Flish列表。Flush列表用来管理将脏页刷新回磁盘。

1.2.3 重做日志缓冲

       重做日志记录每次修改后的最新值,InnoDB首先将重做日志信息放入到重做日志缓冲区,然后按一定频率将其刷新到重做日志文件。

       重做日志缓冲中的内容会在以下三种情况下刷新到磁盘的重做日志文件中:

  1. Master Thread每一秒将重做日志缓冲刷新到重做日志文件;
  2. 每个事务提交时会将日志缓冲重新到重做日志文件;
  3. 当重做日志缓冲池剩余空间小于1/2时,日志缓冲重新到重做日志文件;

1.2.4 额外的内存池

       在对一些数据结构本身的内存进行分配时,需要重从额外的内存池中进行申请,当该区域的内存不够时,会从缓冲池中进行申请。

2. Checkpoint 技术

       前面说过,为了提升效率,缓冲池中的页被修改后,并没有立即将脏页刷入磁盘,而是以一定的频率进行刷入。但是如果还没有刷入,此时发生宕机,那么数据就不能恢复。

       为了解决该问题,当前事务数据库系统普遍都采用了 Write Ahead Log 策略,即当事务提交时,先写重做日志,在修改页。当由于发生宕机而导致数据丢失时,通过重做日志来完成数据的恢复

       Checkpoint技术的目的是解决以下几个问题:

  • 缩短数据库的恢复时间;

              发生宕机时,不需要重做所有日志,只需对Checkpoint之后的重做日志进行恢复,这样大大缩短了恢复时间。Checkpoint之前的页都已经刷入磁盘了。

  • 缓冲池不够用时,将脏页刷新到磁盘;

              缓冲池不够用时,将强制执行Checkpoint.

  • 重做日志不可用时,刷新脏页。

              重做日志如果有不再需要的部分,则可以被覆盖重用。如果此时还需要使用重做日志,那么必须强制执行Checkpoint,因此这部分就可以被覆盖重用。

2.1 Checkpoint工作原理

       数据库实例崩溃时,内存中的DB_Buffer中的修改过的数据,可能没有写入到磁盘中。数据库在重新打开时,需要进行恢复,来恢复DB Buffer中的数据状态,并确保已经提交的数据被写入到磁盘中。通过它Checkpoint,可以确定重做日志的哪一部分应该被扫描并应用于恢复。

       Checkpoint机制并不是直接将脏页刷回到磁盘的,而是通过double write(两次写)。即通过memcpy函数将脏页复制到内存中的doublewrite buffer,之后通过double write分两次(每次 1 MB)顺序写入共享表空间的物理磁盘上,然后调用fsync函数同步磁盘。

       下文对于两次写以及数据恢复做了详细解释:

       Double Write

       Checkpoint分类

  • Sharp Checkpoint

       Sharp Checkpoint发生在数据库关闭时,将所有的脏页都刷新回磁盘。

  • Fuzzy Checkpoint

       Fuzzy Checkpoint指刷新一部分脏页,而不是刷新所有的脏页回磁盘。

       在以下几种情况会进行Fuzzy Checkpoint

  1. 每秒或每 10 秒的速度从缓冲池的脏页列表中刷新一定比例的页回到磁盘。
  2. 可用空闲页不足 100 个,InnoDB会将LRU列表尾端的页移除。如果这些页中有脏页,需进行Checkpoint
  3. 重做日志不可用时,强制将一些页刷新回磁盘。
  4. 脏页数量太多。

3. InnoDB 关键特性

3.1 插入缓冲

       对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若存在,则直接插入;若不在,则先放入到一个 Insert Buffer 对象中,假装已经插入。数据库这个非聚集索引已经插到叶子节点,而实际并没有,只是存放在另一个位置。然后再以一定的频率和情况进行 Insert Buffer 和辅助索引页子节点的 merge(合并)操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对于非聚集索引插入的性能。

3.2 两次写

       Double Write

3.3 自适应哈希索引

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

       自适应哈希索引对这个页的连续访问模式必须是一样的,访问模式指的是查询的条件一样

WHERE a = xxx
WHERE a = xxx and b = xxx

       若上述两种查询,交替进行上述查询,并不会对该页构造自适应哈希索引。

       自适应哈希索引还有如下要求:

  • 以该模式访问了 100 次
  • 页通过该模式访问了 N 次,其中 N = 页中记录 * 1/16。

3.4 异步 IO

       同步IO指,每进行一次IO操作,需要等待此次操作结束才能继续接下来的操作。

       AIO指用户可以在发出一个IO请求后立即再发出另一个IO请求,当全部IO请求发送完毕后,等待所有IO操作的完成。

3.5 刷新邻接页

       刷新邻接页的工作原理是:当刷新一个脏页时,InnoDB会检测该页所在的区的所有页,如果是脏页,那么一起进行刷新。这样做的好处是,通过AIO可以将多个IO 写入操作合并为一个IO操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值