InnoDB存储引擎

1 MySQL体系结构

  • 数据库文件的集合,是依照某种数据模型存放于存储器中的数据集合
  • 数据库实例程序,是位于用户和操作系统之间的数据管理软件,用户对数据库数据的任何操作都是通过实例进行的

MySQL体系结构

在这里插入图片描述

2 InnoDB存储引擎概述

存储引擎是基于表的,而不是数据库

  • InnoDB存储引擎支持事务,主要面向在线事务处理(OLTP)的应用
  • 特点是行锁设计、支持外键、支持非锁定读
  • 使用多版本并发控制(MVCC)来获得高并发性
  • 实现了SQL的4种隔离级别
  • 使用next-key locking的策略来避免幻读产生
  • 从MySQL4.1开始将每个InnoDB存储引擎的表单独存放到一个独立的ibd文件中

3 InnoDB体系架构

  • 后台线程:主要负责刷新内存池中的数据
  • 内存:维护线程访问的数据结构、缓存磁盘上的数据等

在这里插入图片描述

3.1 后台线程

InnoDB存储引擎是多线程的模型

  • Master Thread:核心后台线程,负责将缓冲池中的数据异步刷新到磁盘,保证数据一致性
  • IO Thread:InnoDB使用AIO(Async IO)来处理写IO请求,IO Thread负责这些IO请求的回调,有10个线程,分别是4个write thread、4个read thread、insert buffer thread、log thread
  • Purge Thread:事务提交后,undolog不再需要,使用Purge Thread来回收
  • Page Cleaner Thread:负责脏页的刷新操作

3.2 内存

在这里插入图片描述

  • 缓冲池:InnoDB存储引擎是基于磁盘存储的,按照页的方式进行管理。缓冲池就是通过内存的速度来弥补磁盘的速度。缓冲池页的大小默认为16KB,页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时触发,而是通过checkpoint的机制刷新回磁盘

    • LRU列表:缓冲池通过最近最少使用LRU算法进行管理,但在InnoDB存储引擎中,LRU列表来加入了midpoint位置,新访问的页并不是加在LRU列表首部,而是放在midpoint位置。InnoDB中,把midpoint之后的列表称为old列表,midpoint之前的列表称为new列表(最活跃的热点数据),并维护一个参数,用于表示mid位置后需要等待多久才能被加入到LRU列表的热端。页从old到new称为page made young,没有从old到new称为page not made young
    • Free列表:当数据库刚启动时,LRU列表是空的,页都放在Free列表中。当需要从缓冲池中分页时,首先从Free列表中查找是否有可用的空闲页,如果有则从Free列表删除,放入LRU列表中;否则根据LRU算法进行淘汰
    • Flush列表在LRU列表中的页被修改后,称为脏页,即缓冲池的页和磁盘上的页不一致。由Flush列表存储,通过checkpoint机制将脏页刷新回磁盘
    • 压缩页:对于非16KB的页,通过unzip_LRU列表管理。例如申请4KB的页,首先检查是否有4KB的空闲页,若没有则检查8KB,将其分成2个4KB,若没有则从LRU列表申请一个16KB的页,将其分成1个8KB和2个4KB
  • 重做日志缓冲:InnoDB首先将重做日志信息放入到缓冲区,然后按一定频率(一般情况,每一秒钟)将其刷新到重做日志文件

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

4 Checkpoint

Write Ahead Log策略当事务提交时,先写重做日志,再修改页。即使由于宕机而导致数据丢失,也能通过重做日志完成数据恢复

检查点技术目的是解决以下问题

  • 缩短数据库恢复时间检查点之前的页已经刷新回磁盘,不需要再恢复
  • 缓冲池不够用时,将脏页刷新到磁盘:根据LRU算法淘汰的页如果时脏页,则强制执行checkpoint,将脏页刷回
  • 重做日志不可用时,将脏页刷新到磁盘:重做日志中不需要恢复的部分可以被重用,如果此时重做日志还需要使用,则强制执行checkpoint,将缓冲池中的页至少刷新到当前重做日志的位置

InnoDB中的两种checkpoint

  • Sharp Checkpoint:发生在数据库关闭时将所有脏页刷新回磁盘
  • Fuzzy Checkpoint:每次只刷新一部分脏页

5 Master Thread

Master Thread具有最高的线程优先级别,内部由多个循环组成,Master Thread根据数据库状态在不同循环中切换

  • 主循环(loop):大多数操作在这个循环中,分为每秒的操作和每10秒的操作
    • 每秒的操作包括
      • 日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
      • 合并插入缓冲(可能)
      • 最多刷新100个脏页到磁盘(可能)
      • 如果当前没有用户活动,切换到background loop(可能)
    • 每10秒的操作包括
      • 日志缓冲刷新到磁盘(总是)
      • 合并最多5个插入缓冲(总是)
      • 刷新100个脏页到磁盘(可能的情况下)
      • 刷新100个或者10个脏页到磁盘(总是)
      • 删除无用的undo页(总是)
  • 后台循环(background loop):如果当前没有用户活动或者数据库关闭时,就会切换到这个循环
    • 删除无用的undo页(总是)
    • 合并20个插入缓冲(总是)
    • 跳回主循环(总是)
    • 不断刷新100个页知道符合条件(可能,跳转到flush loop)
  • 刷新循环(flush loop):如果没有事情做,则跳转到suspend loop
  • 暂停循环(suspend loop):将Master Thread挂起

InnoDB1.0.x版本之后,维护一个参数表示磁盘IO吞吐量,默认为200,合并插入缓冲时,数量为这个参数的5%,刷新脏页时,数量为这个参数

6 InnoDB关键特性

6.1 插入缓冲

使用原因:一个表上有多个非聚集的辅助索引且不是唯一,对于这类的非聚集索引页的叶子节点插入不是顺序的,离散的访问非聚集索引页导致插入操作性能下降

Insert Buffer:对于非聚集索引的插入或更新操作,不是每一次直接插入索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在则直接插入;若不再则先放到Insert Buffer对象中,再以一定的频率进行Insert Buffer和辅助索引页子节点的merge操作,通常能将多个插入合并到一个操作中,提高插入性能

Insert Buffer要同时满足:索引是辅助索引索引不是唯一的

Insert Buffer数据结构:B+树

Change Buffer:可视为Insert Buffer的升级,对一条记录的UPDATE操作分为将记录标记为删除和真正将记录删除

6.2 两次写

由两部分组成,一部分是内存中的doublewrite buffer,大小为2MB,另一部分是磁盘上的128个页,大小为2MB

在对缓冲池的脏页进行刷新时,不直接写磁盘,而是通过memcpy将脏页先复制到内存的doublewrite buffer中,再通过doublewrite buffer分两次,每次1MB顺序的写入磁盘上的doublewrite,完成之后,再将这里面的页写入各个表空间文件中

6.3 自适应哈希索引

InnoDB会监控对表上各索引页的查询,如果建立哈希索引可以提升性能,则建立哈希索引,称为自适应哈希索引AHI

AHI是通过缓冲池的B+树页构造而来,不需要对整张表构建哈希索引

6.4 异步IO

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

6.5 刷新邻接页

当刷新一个脏页时,InnoDB会检测该页所在区的所有页,如果是脏页,那么一起进行刷新

7 InnoDB关闭

在关闭时,参数innodb_fast_shutdown影响着InnoDB的行为

  • 0:数据库关闭时,InnoDB需要完成所有的full purge和merge insert buffer,将所有脏页刷新回磁盘,这需要一些时间
  • 1:默认值,不需要完成上述的full purge和merge insert buffer,但是缓冲池中的脏页还是会刷新回磁盘
  • 2:都不完成,而是将日志写入日志文件,下次数据库启动时,进行恢复操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值