您当前的位置:首页 > 电脑百科 > 数据库 > 百科

浅析 InnoDB 存储引擎的工作流程

时间:2019-11-06 13:52:08  来源:  作者:

InnoDB

InnoDB 是由 Innobase Oy 公司开发,该存储引擎是第一个完整支持 ACID 事务的 MySQL 存储引擎。具有插入缓存、两次写、自适应哈希索引等关键特性,是一个高性能、高可用的存储引擎。

整体架构

InnoDB 有多个内存块,这些内存块组合在一起组成了一个大的内存池。而 InnoDB 的内存池中会有多个后台线程,这些后台线程负责刷新内存池中的数据,和将脏页(已修改的数据页)刷新到磁盘文件。

后台线程

默认情况下,InnoDB 存储引擎有 13 个后台线程:

  • 一个 master 线程
  • 一个锁监控线程
  • 一个错误监控线程
  • 十个 IO 线程
    • 插入缓存线程
    • 日志线程
    • 读线程(默认 4 个)
    • 写线程(默认 4 个)

下面是我本机上的十个 IO 线程

内存池

InnoDB 存储引擎的内存池包含:缓冲池、日志缓存池、额外内存池。这些内存的大小分别由配置文件中的参数决定。其中占比最大的是缓冲池,里面包含了数据缓存页、索引、插入缓存、自适应哈希索引、锁信息和数据字典。InnoDB 会在读取数据库数据的时候,将数据缓存到缓冲池中,而在修改数据的时候,会先把缓冲池中的数据修改掉,一旦修改过的数据页就会被标记为脏页,而脏页则会被 master 线程按照一定的频率刷新到磁盘中。日志缓存则是缓存了redo-log 信息,然后再刷新到 redo-log 文件中。额外内存池则是在对一些数据结构本身分配内存时会从额外内存池中申请内存,当该区域内存不足则会到缓冲池中申请。

浅析 InnoDB 存储引擎的工作流程

 

Master Thread

InnoDB 存储引擎的主要工作都在一个单独的 Master Thread 中完成,其内部由四个循环体构成:主循环( loop )、后台循环( background loop )、刷新循环( flush loop )、暂停循环( suspend loop )。具体工作流程如下图所示:

浅析 InnoDB 存储引擎的工作流程

 

主循环

主要负责将缓冲池中的日志文件刷新到磁盘中、合并插入缓存、刷新缓冲池中的脏页数据到磁盘中、删除无用的 Undo 页、产生一个 checkpoint 。在主循环中会多次将脏页刷新到磁盘中,但是有一些刷新任务总会执行,有一些则根据参数来判断当前是否需要刷新。而这个参数 innodb_max_dirty_pages_pct 最大脏页比例是通过配置文件决定的,你可以根据实际情况来调整你自己的最大脏页比例,来达到最好的性能。

伪代码如下:

后台循环

在后台循环中 InnoDB 会做这些事:删除无用的Undo页、合并插入缓存。如果当前 InnoDB 处于空闲状态,则跳转到刷新循环,否则跳转到主循环继续处理数据。

伪代码如下:

刷新循环

一旦执行到刷新循环,InnoDB 会一直处理脏页数据,直到脏页数据达到最大脏页比例以下。这时候会跳转到暂停循环中(所有数据都处理完毕)。

伪代码如下:

暂停循环

在本循环中,InnoDB会将 Master Thread 挂起,减少内存资源使用,一直处于 waiting 状态,等待事件来唤醒。一旦有新的事件过来,就跳转到主循环中。

伪代码如下:


由此可以看出,master 线程的最大的工作内容就是刷新脏页数据到磁盘了。这一步就是把缓存池中被修改的数据页同步到磁盘中。而脏页数据的刷新基本上都是由innodb_max_dirty_pages_pct 来控制的,所以当你的服务器处理能力比较强,给 InnoDB 分配的内存池比较大,这时候可能你的脏页数据会很难达到最大脏页比,这时候你的数据基本上都在缓冲池中,可能需要很长一段时间才会到数据库磁盘文件中,也就是脏页的刷新速度会很低(MySQL 5.1之前的版本默认是 90%,后面调整到 75%)。所以实际应用中可以根据自己内存和数据库的读写量来设置这个最大脏页比。对于一次刷新脏页数量的设置,在 InnoDB Plugin 中有一个参数 innodb_adaptive_flushing自适应刷新,InnoDB 会根据产生的重做日志速度来计算出当前最适合的刷新脏页数量。当然 InnoDB Plugin 中还有其它很多参数配置,合理利用这些配置可以极大的提升 InnoDB 存储引擎的性能。

关键特性

前面说到 InnoDB 的三大特性分别为:插入缓存、两次写、自适应哈希索引。下面就简单介绍下这三大特性。

插入缓存

当我插入一条数据,该数据只有一个 ID 索引(聚集索引:数据行的物理顺序与列值的逻辑顺序相同)的时候,并且 ID 是自增长的,这时候页中的行记录按照 ID 顺序存放,所以只需要在最新页插入数据即可。但是如果我的表有多个非聚集索引(该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同),在插入的时候非聚集索引的插入不再是顺序的,这时候要离散的访问非聚集索引页,导致插入性能变低。而插入缓存则在插入的时候判断缓冲池中是否存在当前非聚集索引,如果存在则直接插入,否则先插入到一个缓存区,然后再通过 Master Thread 来合并插入缓存。这样极大的提高了数据的写性能。

两次写

两次写是为了解决在将缓冲池中的脏页刷新到磁盘的过程中,操作系统出现故障,导致当前的脏页部分写失效的问题。通过两次写在下次恢复的时候,InnoDB 会根据两次写的结果来恢复数据。

原理:在刷新脏页的时候,不是直接把脏页数据刷新到磁盘,而是将脏页先写到一个大小为2M的内存缓存中,再将这个内存缓存数据同步到磁盘的共享表空间中。当全部都写到共享表空间后,再将数据刷新到磁盘中。这样如果发生了上面描述的情况,这时候数据会在共享表空间中有个备份,恢复的时候就可以使用共享表空间的数据。

如果有数据库集群的情况下,master数据库是一定要开启两次写的,为了保证数据可靠性。而从数据库可以通过参数 skip_innodb_doublewrite 来禁止两次写功能,来提高插入效率。

自适应哈希索引

InnoDB 会监控对表示的索引查找,如果发现可以通过对索引进行哈希来优化搜索。这时候会对当前的索引建立哈希索引。称之为自适应哈希索引( AHI )。可以通过参数innodb_adaptive_hash_index 来禁用或启用此特性。

小结

总体来说 InnoDB 的高性能体现在:插入数据的时候先保存在内存中,直接跟内存交互性能比较好,而且还有插入缓存优化,保证了高并发写操作。高可用则表现在两次写特性,保证了机器宕机或者出故障的时候数据不会丢失。这里只是简单介绍了一下 InnoDB 的工作流程和一些特性,当然 InnoDB 还有很多很多强大的功能,比如说事务、锁、索引、算法等等有兴趣的同学可以参考《 MySQL 技术内幕 InnoDB 存储引擎》这本书深入了解。



Tags:InnoDB   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除,谢谢。
▌相关推荐
很多同学在面试中会被问到数据库的问题,而常被问到的一个问题就是:MySQL 中的 InnoDB 和 MyISAM 之间是什么关系,分别有什么特点?许多同学都把 MySQL 作为自己的数据库,但是可能...【详细内容】
2020-12-08  Tags: InnoDB  点击:(70)  评论:(0)  加入收藏
InnoDBInnoDB 是由 Innobase Oy 公司开发,该存储引擎是第一个完整支持 ACID 事务的 MySQL 存储引擎。具有插入缓存、两次写、自适应哈希索引等关键特性,是一个高性能、高可用...【详细内容】
2019-11-06  Tags: InnoDB  点击:(65)  评论:(0)  加入收藏
对于数据库来讲大多瓶颈都出现在IO问题上,所以现在SSD类的设备也才能大行其道。那数据库的IO这块有什么可以优化的吗? 我这里大致谈一下我的看法,希望能达到一个抛砖引玉的效果...【详细内容】
2019-08-26  Tags: InnoDB  点击:(138)  评论:(0)  加入收藏
概述今天主要介绍一下mysql数据库一般修改InnoDB redo log事务日志文件大小的步骤,然后用一个实验来演示一下,下面一起来看看吧~基本步骤在MySQL 5.5版本里,如果想修改ib_logfi...【详细内容】
2019-07-16  Tags: InnoDB  点击:(309)  评论:(0)  加入收藏
▌简易百科推荐
初学者的数据库索引简介> Congratulations今天在ORM的时代,我们作为开发人员不必经常触摸数据库。我自己自己建立了我的第一个项目而不在项目内写一行的原始SQL。它起初工作...【详细内容】
2021-07-12  闻数起舞    Tags:SQL查询   点击:(5)  评论:(0)  加入收藏
如果一切似乎都在控制下,你就不会够快”> Photo by Christina Morillo (original). Thank you!几乎所有用于最终用户的Web服务都需要存储数据。它们几乎所有所有人都将它们存...【详细内容】
2021-07-12  闻数起舞    Tags:数据库性能   点击:(5)  评论:(0)  加入收藏
系统数据库和用户数据库数据库有两种:系统数据库,另一种是需要用户创建的数据库,右键新建数据库(称之为用户数据库) 创建数据库必须了解的概念要创建自己的数据库,首先要弄清楚两...【详细内容】
2021-07-09  技术小菜    Tags:数据库   点击:(6)  评论:(0)  加入收藏
分库分表介绍:分库分表的目的是为了系统高并发、高可用。分库和年发表是两回事,两个概念,都是为了防止数据库服务因为同一时间内访问量过大导致宕机而设计的一种应对策略。一、...【详细内容】
2021-06-28  从孩子开始学编程    Tags:分库分表   点击:(16)  评论:(0)  加入收藏
本文讲解窗口函数的概念,窗口函数与数据分组的功能相似,可以指定数据窗口进行统计分析,但窗口函数与数据分组又有所区别,窗口函数对每个组返回多行,而数据分组对每个组只返回一行...【详细内容】
2021-06-25  大话数据分析    Tags:SQL数据分析   点击:(15)  评论:(0)  加入收藏
MongoDB 简介MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。它的最大特点是:•特别适合存储大量的无结...【详细内容】
2021-06-25  锐玩道    Tags:MongoDB   点击:(25)  评论:(0)  加入收藏
class Integration(Base, ModelBase, ModelSerializer): __tablename__ = 'integration' id = Column(Integer, primary_key=True) domain = relationship...【详细内容】
2021-06-24  lizhihua0625    Tags:sqlalchemy   点击:(16)  评论:(0)  加入收藏
我们渴望通过数据来增强和改善商业和生活的各个方面,这驱使我们在大规模管理数据方面进行范式转变。 尽管过去十年的技术进步已解决了数据量和数据处理计算的规模问题,但它们无法解决其他方面的规模问题:数据格局的变化,...【详细内容】
2021-06-23  ThoughtWorks  今日头条  Tags:Data Mesh   点击:(19)  评论:(0)  加入收藏
一. 前台管理1. 轮播图(5张),首页头部大图,注册登录页左侧大图,logo图,导航条广告二. 后台管理1. 站点用户管理1. 系统用户 SystemUser 列名 数据类型 ...【详细内容】
2021-06-23  大壮二壮学剪辑    Tags:数据库表   点击:(15)  评论:(0)  加入收藏
阿里云Tair云原生内存数据库线上名字为阿里云数据库Redis企业版(又称阿里云Tair),从2009年开始正式承载集团业务,是一款历经磨练的企业级产品。它完全兼容Redis的数据结构和通讯协议,包括API接口,并且在内部逐步打磨的过程...【详细内容】
2021-06-21  数据库技术达摩院    Tags:Tair云   点击:(18)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条