1.概述

是一个高性能、高可用、高扩展的存储引擎。

2.InnoDB体系架构

InnoDB存储引擎主要由内存池和后台线程构成。

其中,内存池由许多个内存块组成,作用如下:

  • 维护所有进程和线程需要访问的内部数据结构。
  • 缓存磁盘上的数据,提高处理器读取速度,当数据被修改的时候也是先修改这里的数据,再被后台线程写到内存上去。
  • 重做日志(redo log)缓冲。

后台线程的主要作用:

  • 负责刷新内存池中的数据,以保证缓冲池中数据是最近的数据。
  • 将缓冲中的数据刷新到磁盘上。
  • 保证数据库发生异常的时候 ,数据库恢复到原先正常的状态。

后台线程

后台线程由很多类型,主要包括:

  1. Master Thread
    最核心的后台线程,主要负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲、undo页的回收。
  2. IO Thread
    InnoDB中大量使用了AIO来处理些的IO请求,提高数据库性能,这个线程的作用就是负责这些IO的回调。
  3. Purge Thread
    用来已经使用并分配的undo 页。
  4. Page Cleaner Thread
    减轻master线程的工作,将脏页的刷新操作放到了这个线程里单独完成。

内存

  1. 缓冲池
    用于弥补CPU和磁盘速度差距太大的问题,CPU直接操作缓冲,然后由其他线程将在缓冲和磁盘之间做衔接。
    缓冲池中的数据类型有索引页、数据页、undo页、插入缓冲、自适应哈希索引、锁信息和数据字典信息等。

  2. LRUList 、Free List 和 Flush List

    • LRU列表是用来管理已经被读取的数据页。
    • Free列表是用来存储没有被使用的空闲页。
    • Flush列表用来存储被修改过的脏页,脏页既存在于LRU列表,也存在于Flush列表。LRU列表管理缓冲池中页的可用性,二Flush列表管理将页刷新回磁盘,二者不影响。
  3. 重做日志缓冲
    线程先将重做日志放到这个缓冲区,然后将按一定频率将其刷新到重做日志文件。

  4. 额外的内存池
    数据结构本身的内存进行分配的时候,先从额外的内存池中进行申请,这里不够,才从缓冲池里申请。

InnoDB缓冲池的LRU机制

朴素的LRU就是利用一个先进先出的队列,将最近用的使用的页放在队列的前端,最久远使用的页就会被排挤到后面,当缓冲池满了的时候,就将后面的页出队。

LRU的作用

提高缓冲区的利用率和降低CPU读取数据的总时间。每次CPU读取数据,会先去缓冲池里找,如果命中了,就直接提交;如果没有,就会去磁盘里提取,然后存储在缓冲区。因为缓冲池的大小是有限的,只能让部分数据存在里面,LRU算法就是确定哪些数据该留在缓冲区,哪些数据该被丢掉。

InnoDB的LRU优化

InnoDB对传统的LRU算法做了一些优化。在LRU队列中加入了midpoint位置,对于新加入的页,不会被直接放大列表头部,而是插入到midpoint的位置,一般默认位置是5/8长度处。midpoint前面的队列称为热点数据,而后面的就是old数据。
InnoDB通过一个时间参数,规定将读取到页等待多久的时间就会被加入到LRU队列的热点部分。

为什么需要加入midpoint?

如果采用朴素的LRU算法,将新添加的页直接放到头部,这样,可能会将热点的数据挤出去,从而降低了效率。通过加入midpoint,可以将热点的数据一直维持在midpoint之前的位置,将不常用的数据放在之后,这样,不常用的数据更有可能被先丢出去啊。
而新添加的数据还不知道是不是一个热点的数据,所以先放在midpoint位置上,然后通过midpoint和时间参数的配合,就能判断它是不是热点的。这样热点的数据就尽量不会被刷出。

undo log 和 redo log

在上面出现了undo log 和redo log 两个内容,在这里解释区分一下。
数据库通常借助日志来实现事务,常见的有undo log、redo log,undo/redo log都能保证事务特性,undolog实现事务原子性,redolog实现事务的持久性。

  • undo log
    记录中存储的是老版本数据,当一个旧的事务需要读取数据时,为了能读取到老版本的数据,需要顺着undo链找到满足其可见性的记录。

  • redo log
    就是保存执行的SQL语句到一个指定的Log文件,当mysql执行数据恢复时,重新执行redo log记录的SQL操作即可。

作用:

  • 数据持久化
    redo log占满的时候,就会将相应的脏页写到内存,然后释放log。
  • 数据恢复
    如果出现宕机,就能重新执行redo log中的语句,恢复缓存中的数据。

3.Checkpoint 技术

数据库线程需要将脏页从缓存池中刷新到磁盘,如何控制刷新的时间和频率对数据库的性能和防止数据丢失就很重要。

作用

  • 缩短数据库的恢复时间。
  • 缓冲池不够用的时候,将脏页刷新到磁盘。
  • 重做日志不可用的时候,刷新脏页。

具体的就是每次刷新多少脏页到磁盘,每次读取哪些脏页,什么时候出发刷新。

具体实现

InnoDB将CheckPoint分为两种:

  • Sharp CheckPoint
    用于在数据库关闭的时候将所有脏页都刷新回磁盘。也可以设置运行的时候使用 Sharp CheckPoint,但是这样回降低数据库的可用性。
  • Fuzzy CheckPoint
    只刷新部分脏页。

Fuzzy CheckPoint的发生条件

  1. Master Thread CheckPoint
    这个检查点由Master线程发起,频率一般是每秒或者每十秒。是异步的,不会阻塞用户查询线程。
  2. Flush_LRU_List CheckPoint
    需要保证LRUList中一直有100个空闲页,如果没有,就要将尾部的页移除,如果这些页中有脏页,这个检查点起作用了。
  3. Async/Sync Flush CheckPoint
    指重做日志文件不够的情况下,需要将一些页刷新回磁盘,这样就能释放一部分重做日志的空间。此时的脏页是从脏页列表中获取的。
  4. Dirty Page too much Checkpoint
    脏页数量太多,就强制执行检查点。

4.Master Thread 工作方式

由多个循环组成,包括主循环、后台循环、刷新循环和暂停循环。

主循环

主循环包括两个部分:每秒一次的操作和每十秒一次的操作。

每秒一次的操作包括:

  • 日志缓冲刷新到磁盘(总是)。
  • 合并插入缓冲(可能)。
  • 最多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能)。
  • 日过没有用户活动,则切换到background loop(可能)。

所谓可能,就是不会每次都发生的操作。

每十秒一次的操作包括:

  • 刷新100个脏页到磁盘(可能)。
  • 至多合并5个插入缓冲(总是)。
  • 将日志缓冲刷新到磁盘(总是)。
  • 删除无用的undo页(总是)。
  • 刷新100个或者是10个脏页的磁盘(总是)。会根据脏页比例控制刷新数量。

后台循环

如果没有用户活动或者数据被关闭了,就会切换到这个循环。

执行的操作包括:

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

线程挂起

如果刷新循环都没有事情可以做,就会被切换到暂停循环,将master thread挂起。

版本改进

之前的刷新数量都是硬编码,是写死的。就会出现刷新数量低,线程忙不过来的问题。

后来改进这个问题,将刷新的数量与合并插入缓冲的数量设置为百分比,根据系统性能做出更改。还有就是自适应刷新,根据脏页的比例,控制刷新频率。

对于脏页的刷新操作,被从master线程中分离到了单独的page cleaner线程中了。

5.InnoDB关键特性

插入缓冲

Insert Buffer

解决问题:对于使用非聚集索引,插入操作不再是顺序的,需要离散地访问非聚集索引页,由于随机读取导致插入操作的性能下降。

目的:提高非聚集索引插入的性能。

实现原理:对于非聚集索引的插入和更新操作,先判断插入的非聚集索引页是不是在缓冲池中,如果在,就直接插入;如果不在,就先放到一个插入缓冲对象,标记为已插入,然后就等待到以后以一定频率和情况进行真正的插入缓冲和辅助索引页子节点的合并操作。这样可以将多个插入合并到一个操作中,大大提高了非聚集索引的性能。

使用插入缓冲需要两个条件:

  • 索引是辅助索引。
  • 索引不是唯一的。

Change Buffer

插入缓冲的升级版。

包括Insert Buffer、Delete Buffer、Purge Buffer,分别对应INSERT DELETE UPDATE操作的缓冲。

对记录进行UPDATE操作可能分为两个过程:标记已删除,真正删除记录。

Insert Buffer 内部实现

数据结构就是一棵B+树。

当辅助索引需要插入到页的时候,如果这个页不在缓冲池中,那么引擎就先构造一个search key,接下来查村Insert Buffer这棵B+树,然后将这个记录插入到树的叶子节点中去。

叶子节点的信息包括记录的表空间ID,页所在的偏移量,记录的插入顺序等。

缓冲中的记录如何合并到真正的辅助索引中呢?

三种情况回进行合并操作:

  • 辅助索引页被读取到了缓冲池当中;
  • 辅助索引页已经无可用空间;
  • 主循环中的合并。

两次写

目的:提高数据的页的可靠性。

工作原理:对缓冲池中的脏页进行刷新的时候不会直接写到磁盘,而是先将脏页复制到内存的doublewrite buffer中,然后通过这个buffer分两次写到共享表空间的物理磁盘上,然后再同步磁盘。

自适应哈希索引

目的:一般通过B+树来查询定位页,查询次数取决于树的高度,一般为三到四层,也就是要查三到四次,而通过哈希索引就只需要查一次就能定位到数据。但是不能为所有数据都建立哈希索引,开销上可能划不来。

作用:引擎对表上各项索引进行查询,如果观察到的建立哈希索引可以带来速度提升,就建立哈希索引,这就是自适应哈希索引。

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

异步IO

提高磁盘的操作性能,当前的数据库都是采用异步IO来操作磁盘。

刷新邻接页

工作原理:当刷新到一个脏页的时候,存储引擎就会顺便检测该页所在区的所有页,如果存在脏页,就一起刷新了,这样可以将多个IO合并为一个IO进行操作,大大提高对机械磁盘的操作性能。

总结

通过这一节内容,很好地理解和总结了InnoDB的相关知识,尤其是LRU、插入缓冲部分,如果学习过操作系统,那么将会对内存管理相关等知识得到一个更全面和深刻的理解。

MySQL技术内幕InnoDB存储引擎(二)——InnoDB存储引擎的更多相关文章

  1. MySQL技术内幕读书笔记(二)——InnoDB存储引擎

    目录 InnoDB存储引擎 InnoDB存储架构 Checkpoint技术 Master Thread 工作方式 InnoDB关键特性(放一下,感觉看后面,再看总结吧) InnoDB存储引擎 Inno ...

  2. 《MySQL技术内幕:InnoDB存储引擎(第2版)》书摘

    MySQL技术内幕:InnoDB存储引擎(第2版) 姜承尧 第1章 MySQL体系结构和存储引擎 >> 在上述例子中使用了mysqld_safe命令来启动数据库,当然启动MySQL实例的方 ...

  3. 《mysql技术内幕 InnoDB存储引擎(第二版)》阅读笔记

    一.mysql架构 mysql是一个单进程多线程架构的数据库. 二.存储引擎 InnoDB: 支持事务 行锁 读操作无锁 4种隔离级别,默认为repeatable 自适应hash索引 每张表的存储都是 ...

  4. Mysql技术内幕——InnoDB存储引擎

    Mysql技术内幕——InnoDB存储引擎 http://jingyan.baidu.com/article/fedf07377c493f35ac89770c.html 一.mysql体系结构和存储引 ...

  5. mysql技术内幕InnoDB存储引擎-阅读笔记

    mysql技术内幕InnoDB存储引擎这本书断断续续看了近10天左右,应该说作者有比较丰富的开发水平,在源码级别上分析的比较透彻.如果结合高可用mysql和高性能mysql来看或许效果会更好,可惜书太 ...

  6. Mysql技术内幕之InnoDB锁探究

    自7月份换工作以来,期间一直在学习MySQL的相关知识,听了一些视频课,但是一直好奇那些讲师的知识是从哪里学习的.于是想着从书籍中找答案.毕竟一直 看视频也不是办法,不能形成自己的知识.于是想着看书汲 ...

  7. 《[MySQL技术内幕:SQL编程》读书笔记

    <[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...

  8. 读书笔记-《Mysql技术内幕》

    MYSQL 技术内幕 Mysql体系 连接池组件 管理服务和工具 SQL接口 查询分析器 优化器 缓冲 插件式存储引擎 物理文件 存储引擎 InnoDB(默认引擎) 支持事务 行锁设计 多版本并发控制 ...

  9. MySQL技术内幕(一)

    MySQL技术内幕 2. InnoDB存储引擎 2.1 InnoDB存储引擎概述 特点:行锁设计.支持MVCC.支持外键.提供一致性非锁定读 2.2 InnoDB体系架构 2.2.1 后台线程 Inn ...

  10. 好书推荐之Mysql三剑客 :《高性能Mysql》、《Mysql技术内幕》、《数据库索引设计与优化》

    Mysql三剑客系列书籍: 大佬推荐 首先推荐<高性能 MySQL>,这本书是 MySQL 领域的经典之作,拥有广泛的影响力.不但适合数据库管理员(DBA)阅读,也适合开发人员参考学习.不 ...

随机推荐

  1. 使用 JavaScript 操作浏览器历史记录 API

    History 是 window 对象中的一个 JavaScript 对象,它包含了关于浏览器会话历史的详细信息.你所访问过的 URL 列表将被像堆栈一样存储起来.浏览器上的返回和前进按钮使用的就是 ...

  2. Vue 组件化开发之插槽

    插槽的作用 相信看过前一篇组件化开发后,你对组件化开发有了新的认识. 插槽是干什么的呢?它其实是配合组件一起使用的,让一个组件能够更加的灵活多变,如下图所示,你可以将组件当作一块电脑主板,将插槽当作主 ...

  3. [原题复现][2020i春秋抗疫赛] WEB blanklist(SQL堆叠注入、handler绕过)

    简介 今天参加i春秋新春抗疫赛 一道web没整出来 啊啊啊 好垃圾啊啊啊啊啊啊啊  晚上看群里赵师傅的buuoj平台太屌了分分钟上线 然后赵师傅还分享了思路用handler语句绕过select过滤.. ...

  4. Postman设置自动捕获传递Cookie教程

    目录 前言 一.安装 1.Postman安装Install Interceptor Bridge 2.谷歌浏览器安装扩展Postman Interceptor 二.使用 1. 打开Capture Co ...

  5. 攻克solo第六课(大调音阶与真的爱你)

    在本期文章中,笔者将通过guitar pro7和大家分享大调音阶的知识. 不知道大家有没有试着使用my song book里面的谱子,反正笔者是觉得赚大了,并且找了囊括民谣.爵士到摇滚在内不同风格的谱 ...

  6. 如何将MathType恢复出厂设置

    必大家都知道,我们日常使用的手机是自带恢复出厂设置功能的,其实除了手机,咱们今天要说的这款公式编辑器MathType,也是可以进行恢复出厂设置操作的哦,下面就让小编给大家介绍一下吧. 一.打开Math ...

  7. 方格取数(number) 题解(dp)

    题目链接 题目大意 给你n*m个方格,每个格子有对应的值 你从(1,1)出发到(n,m)每次只能往下往上往右,走过的点则不能走 求一条路线使得走过的路径的权值和最大 题目思路 如果只是简单的往下和往右 ...

  8. 企业安全03Django GIS SQL注入漏洞CVE-2020-9402

    Django GIS SQL注入漏洞CVE-2020-9402 一.漏洞描述 Django是Django基金会的一套基于Python语言的开源Web应用框架.该框架包括面向对象的映射器.视图系统.模板 ...

  9. Python爬虫入门(二)之Requests库

    Python爬虫入门(二)之Requests库 我是照着小白教程做的,所以该篇是更小白教程hhhhhhhh 一.Requests库的简介 Requests 唯一的一个非转基因的 Python HTTP ...

  10. Intel s2600系列做虚拟化需要注意的item

    Intel s2600cw\cp主板做虚拟化BIOS需要设置以下选项,附件为截图供参考. -->vt,cpu虚拟化,默认关闭,需要确保开启 -->ht,cpu超线程,默认开启,需要确保开启 ...