InnoDB 存储引擎详细解析

InnoDB存储引擎详细解析


仅作为笔记


前言

仅作为笔记


一、InnoDB 存储引擎概述

  • 从MySQL5.5版本开始,InnoDB成了默认的表存储引擎。
  • 第一个完整支持ACID事务的MySQL存储引擎
  • 支持行锁、支持MVCC、支持外键、提供一致性非锁定读。

二、InnoDB 存储引擎的版本

  • 各个版本的InnoDB对比。
    在这里插入图片描述

三、InnoDB 体系架构

  • InnoDB存储引擎由许多个内存块构成,不是一个单一的内存块,由许多内存块组成了一个大的内存池。如下图:
    在这里插入图片描述

  • 主要功能包括(部分):
    1)维护所有线程/进程需要访问的多个内部数据结构。
    2)缓存磁盘上的数据,方便快速的读取,同时在对磁盘文件的数据修改之前在这里缓存。
    3)重做日志缓冲。

3.1 后台线程

  • 先知道一个概念:脏页,当内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页”内存数据写入到磁盘后,内存和磁盘上的数据页的内容就一致了,称为“干净页”

  • 后台线程的作用
    1)刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。
    2)此外将已修改的数据文件刷新到磁盘文件
    3)保证在数据库发生异常的情况下InnoDB能恢复到运行状态

  • 多样的后台线程:首先知道这个存储引擎是多线程的模型,因此后台线程也是多种多样的。
    1)Master Thread:核心的后台线程,主要是负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性包括脏页的刷新(在1.2后会交给Page Cleanner Thread线程完成)
    2)IO Thread:InnoDB使用了大量的AIO来处理写IO请求IO Thread的工作主要是负责这些IO的回调处理。IO Thread有四种:write(在InnoDB1.0后增加到四个),read(在InnoDB1.0后增加到四个),insert buffer,log IO thread。
    3)Purge Thread
    回收事务被提交后所使用的undolog,在InnoDB1.1版本之前,purge操作仅在InnoDB存储引擎的Master Thread中完成,而InnoDB1.1版本开始之后可以独立出去了。而在1.2版本之后支持多个Puege Thread了
    4)Page Cleanner Thread:作用是将脏页的刷新操作都放入到单独的线程中来完成。于1.2版本引进,目的是为了减轻Master Thread的工作及对于用户查询线程的阻塞,提高InnoDB的性能。

3.2 内存

先知道这个:InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理,因此可将其视为基于磁盘的数据库系统(Disk-base Database)

  • 缓冲池:简单来说就是一块内存区域,用来弥补磁盘读写速度跟不上cpu速度所带来的数据库性能影响首先判断该页是否存在缓冲池中,若存在缓冲池中,称该页也在缓冲池中被命中,直接读取该页,否则读取磁盘上的页。对于数据库中的页修改操作,首先修改在缓存池中的页,然后再以一定的频率刷新到磁盘上,刷新操作并不是一发生了页更改就写,而是通过Checkpoint机制刷新回磁盘
    要点1) 缓冲池缓存的数据类型:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB存储的锁信息(lock info)、数据字典信息(data dictonary)。其中数据页和索引页占比最大,如下:
    在这里插入图片描述
    要点2)从1.0.x版本开始,缓冲池实例可以有多个,每个页根据哈希值平均分配到不同的缓存池实例中,减少数据库内部竞争,增加数据库的并发处理能力

  • LRU List、Free List和Flush List
    1)LRU ListLRU算法用来管理缓冲池(最频繁使用的页在LRU列表的前端,而最少使用的页在LRU列表的尾端)。当缓冲池不能存放新读取到的页时,将优先淘汰LRU列表中尾端的页。在InnoDB中,LRU列表中加入了midpoint位置新读取到的页,虽然是最新访问的页,但并不是直接放入到LRU列表的首部,而是放入到LRU列表的midpoint位置。在默认配置下,该位置在LRU列表长度的5/8处midpoint之后的列表称为old列表,之前的列表称为new列表InnoDB存储引擎引入了innodb_old_blocks_time参数,用于表示页读取到mid位置后需要等待多久才会被加入到LRU列表的热端。以此来保证真正的热数据被加入到LRU列表的热端。
    2)Free List:从上面可以知道,LRU就是一个用来管理已经读取到的页的工具,而当数据库刚启动的时候,LRU列表是空的,这时页都存放在Free列表中。当需要从缓冲池中分页时,首先从Free列表中查找是否有可用的空闲页,若有则将该页从Free列表中删除,放入到LRU列表中若没有,再根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页。当页从LRU列表的old部分加入到new部分时,称此时发生的操作为page made young,而因为innodb_old_blocks_time的设置而导致页没有从old部分移动到new部分的操作称为page not made young。
    3)Flush List存储脏页的列表,注意,脏页既存在于LRU列表中(因为LUR列表就是存放缓冲池数据的地方,意味着在修改页时修改的是这里,所以这里也存放脏页),也存在于Flush列表中LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者互不影响

  • 重做日志缓存(redo log buffer)存放重做日志信息的地方,然后按照一定的频率将其刷新到重做日志文件

  • 额外的内存池也就是管理内存的那些结构或者说是实例所需要的资源从额外的内存池申请。如:分配了缓冲池,但是每个缓冲池需要缓冲帧,还有对应的缓冲控制对象。这些资源就要重额外的内存池申请。

四、Checkpoint技术

  • Checkpoint技术的目的
    1)缩短数据库的恢复时间。数据库在发生宕机时,其使用重做日志进行恢复,但是当运行时间太久了,需要恢复的日志就很多,造成恢复时间长,而使用Checkpoint技术后指需要恢复上一个Checkpoint到现在的重做日志就行了,从而缩短了数据库的恢复时间。
    2)缓冲池不够用时,将脏页刷新到磁盘上。缓冲池的大小也是有限的,当缓冲池不够用了就会将最底层的溢出,而如果溢出的这个是脏页就会触发Checkpoint把脏页写道磁盘。
    3)重做日志不可用时,刷新脏页。重做日志本身是用来数据库宕机时恢复用的,重做日志的设计之初是循环使用的(数据库需要一直运行,不可能设计一个可以一直增加的重做日志),那么重做日志就会分为两部分,一是已经被写进了磁盘了的,那么这部分就会变成可以覆盖的,如果需要发生数据恢复也用不到他了,也就是可用的重做日志部分(可以写进其他的重做记录了),另一部分就是还没写进磁盘,如果遇到数据恢复还需要的部分,这部分呢就可以采用Checkpoint进行脏页刷新,将脏页刷新到磁盘中去,至少将缓存中的页刷新到当前重做日志的位置。

  • 不同的Checkpoint:说半天,Checkpoint无非是将缓冲池中的脏页刷新进磁盘而已,不同的地方在于每次刷新多少到磁盘,刷新的在脏页从哪里来,以及什么时候触发Checkpoint。大致分为两种:
    1)sharp Checkpoint:发生在数据库关闭的时候,全盘将所有的脏页刷新进磁盘
    2)Fuzzy Checkpoint:刷新部分脏页,运用在数据库在运行时。有四种需要运行这个checkpoint的情况.1、MasterThread Checkpoint:异步刷新,每秒或每10秒从缓冲池脏页列表刷新一定比例的页回磁盘。2、FLUSH_LRU_LIST Checkpoint用于维护LRU列表是否有足够的空间操作。3、Async/Sync Flush Checkpoint保证重做日志的可用性。4、Dirty Page too much Checkpoint脏页太多,强制checkpoint.保证缓冲池有足够可用的页

五、 InnoDB 关键特性

5.1 插入缓冲

  • 数据页一样,是物理页的一个组成部分,其数据结构是一棵B+树,存放在ibdata1(共享表空间)中。
  • 使用insert buffer的条件:索引是辅助索引索引不是唯一的。

5.2 两次写

  • 用于应对部分写失效的情况
  • 部分写失效:InnoDB正在写一个页,此时仅写了一部分发生了宕机,这种情况叫部分写失效。如下图为两次写:
    在这里插入图片描述

5.3 自适应哈希索引

  • InnoDB存储引擎会监控对表上各个索引页的查询,如果观察到建立哈希索引可以带来速度提升,则建立哈希索引。这就叫自适应哈希索引。

5.4 异步IO

  • 也就是AIO关于BIO、NIO、AIO我在其他部分有详细介绍,可以点击这里查看。

5.5 刷新邻接页

  • 当刷新一个脏页时,InnoDB存储引擎会检测到该页所在区的所有页,如果是脏页那么一起刷新
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值