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. 在Linux下的安装mysql-5.7.28 心得总结

    mysql-5.7.28 在Linux下的安装教程图解 这篇文章主要介绍了mysql-5.7.28 的Linux安装,本文通过图文并茂的形式给大家介绍的非常详细,具有一定的参考借鉴价值,希望给有需要的 ...

  2. maven 笔记2

    maven 中央工厂的位置:D:\dubbo\apache-maven-3.2.5\lib D:\dubbo\apache-maven-3.2.5\lib pom-4.0.0.xml reposito ...

  3. 编译一个支持多线程的php安装包

    前言 因为项目上的需要,需要用到php,一般来说,用默认的版本和配置就可以满足大多数的场景,因为需要加入多线程,所以需要自己编译一个包 一般来说,发行的包的版本的配置选项和代码都是最稳定的,所以在大多 ...

  4. 说说基于网络的五种IO模型

    # django不是一个异步框架 # tornado是异步的web框架 # 处理每秒大量的请求 # 个人理解的IO:就是应用层与内核驱动层的交互,这个过程无论从应用层到内核中,还是驱动层等待硬件层的数 ...

  5. FTP的PORT(主动模式)和PASV(被动模式)

    最近做一个项目用到FTP和其它系统进行文件传输,结果在FTP网络连接的问题上花了很多时间,由于太久没搞多FTP,忘记了FTP不单单开放21端口,客户端采用不同连接模式对网络有不同.在此重温一下FTP的 ...

  6. sqlilab less23-less27a

    less23 本关过滤掉了注释符号-- 和#,并且变量带入数据库时被单引号包裹.需要将后边的单引号闭合.使用and '1'='1,将其加在注入语句的末尾,使用suffix参数 less-24 以后填坑 ...

  7. 看看吧!月薪20K以上的程序员才能全部掌握RabbitMq知识,你掌握了多少

    一.RabbitMq基础知识 0.概述 消息队列的作用就是接收消息生产者的消息,然后将消息发送到消费者 1.信道channel 我的理解是生产者/消费者和rabbitmq交互的一个通道,负责交换机.队 ...

  8. 深度分析:面试腾讯,阿里面试官都喜欢问的String源码,看完你学会了吗?

    前言 最近花了两天时间,整理了一下String的源码.这个整理并不全面但是也涵盖了大部分Spring源码中的方法.后续如果有时间还会将剩余的未整理的方法更新到这篇文章中.方便以后的复习和面试使用.如果 ...

  9. Guitar Pro 教程之有效的几种泛音

    学习音乐的朋友们都知道,泛音的种类分为好几种,一般分为自然泛音和人工泛音,击弦泛音,拨片泛音,半泛音等等.本章节采用图文结合的方式讲解{cms_selflink page='index' text=' ...

  10. 10万级etl批量作业自动化调度工具Taskctl之轻量级Web应用版

    什么是批量作业: 批量处理是银行业整个信息后台最为重要的技术形态,也是银行核心信息资产数据的分享.传输.演化的重要技术手段.有调查指出,全球70%的数据是经过批量处理得以再次使用,可见批量处理在整个信 ...