MySQL之InnoDB引擎(一)

2023-10-26

1.InnoDB介绍

InnoDB是一个通用的存储引擎,同时具备高可靠性与高性能的特性,除非用户指定存储引擎的类型,否则其作为MySQL Server的默认存储引擎。

使用InnoDB存储引擎的优势包括如下几点:

  • DML操作符合ACID模型,使用事务提交、事务回滚以及故障恢复的措施保护用户数据的安全
  • 支持行级锁以及一致性读,能提升多用户使用场景下的并发性以及性能
  • 数据表使用主键优化查询来自磁盘中的数据记录,每个数据表都有一个被称之为聚簇索引的主键索引,使用该索引查询数据的时候可以最小化I/O次数
  • 使用外键约束措施保证数据的完整性,当执行增加、更新、删除操作时会检查相关联的数据表从而保证相关联数据记录的一致性

下表列出了InnoDB存储引擎的特性:

特性

支持

B-tree索引

备份与恢复

集群数据库

聚簇索引

数据缓存

数据加密

外键约束

全文检索

地理空间数据类型

地理空间索引

哈希索引

索引缓存

锁粒度

行级

MVCC

主从复制

存储容量

最大64TB

T-tree索引

事务

数据字典的统计

表1 InnoDB存储引擎的特性

2.InnoDB架构

下图是InnoDB的总体架构图,包括两个部分:内存存储架构与磁盘存储架构

​​​​​​​​​​​​​​

图1 InnoDB的总体架构

2.1内存存储架构

内存存储架构主要包括数据缓存与数据缓冲的管理,包括如下几个部分:缓冲池、缓冲变化、适应性哈希索引、缓冲日志。

2.1.1缓冲池(Buffer Pool)

缓冲池是一块来自主内存的区域,InnoDB使用该区域缓存数据表以及索引需要访问的数据。缓冲池缓存了频繁被使用的数据,这种直接访问内存数据的方式可以大幅提升数据处理的性能。在数据库专用服务器中,缓存池占用物理内存的比例可以达到80%。

为了提升数据按列读的访问效率,InnoDB对缓冲池进行分页式管理,其中每页包含多行记录,所有页是以链表的数据结构实现存储管理。缓存的淘汰策略使用变异的LRU算法,该策略能淘汰最近最少被使用的数据。

因此,使用缓冲池去管理热点访问的数据是MySQL调优中一个非常重要的手段。

2.1.1.1缓冲池LRU算法

InnoDB使用变异的LRU算法以链表的数据结构管理缓冲池,也就是,需要增加一个新页到缓冲池的时候,最近最少被使用的页将被淘汰出缓存池,新页将被增加到页链表的中间位置,中间位置插入策略把链表分成两个子链表:

  • 头部子链表,保存最近被访问的新页列表
  • 尾部子链表,保存最近很少被访问的旧页列表

如下图所示:

图2 缓冲池链表数据结构图

从上图可知,LRU算法在新子链表(New Sublist)中保存频繁被使用的页,在旧子链表(Old Sublist)中保存非频繁被使用的页,这些很少被使用页将会逐渐被LRU算法淘汰出缓冲池。

默认地,LRU算法以下列方式运作:

  • 3/8的缓冲池空间被分配给旧子链表,5/8的缓冲池空间被分配给新子链表
  • 缓冲池链表的中间位置(Midpoint)是新子链表的尾部与旧子链表的头部相连接的地方
  • 当InnoDB从磁盘重读取一页数据到缓冲池时,一开始时插入到旧子链表的头部位置(Midpoint)。用户进行SQL查询时,InnoDB从缓存中读取并返回页数据,有些数据页是预读取到缓冲池的,其目的是提高SQL查询性能。
  • 如果在旧子链表的数据页被用户SQL查询读取,则该数据页会立刻被插入到新子链表的头部,如果是预读取的数据页,则不会被立刻更新到新子链表中。但是,如果预读取数据页自始至终都没有被读取,则最终都会被淘汰出缓冲池。如上图所示,右边的垂直向上的直线(Accessed pages),其表示的意义是,被读取访问的数据会被插入到新子链表的头部,是更新趋势。
  • 随着数据库持续地被SQL查询操作,旧子链表与新子链表中的被读取的数据页都会被增加到新子链表的头部,旧子链表的被读取的数据页也会被增加到中间位置(Midpoint)。如上图所示,右边的垂直向下的直线(Unused pages),其表示的意义是,最终未被读取的数据页都会被挤到旧子链表尾部,并最终被淘汰出缓冲池,是淘汰趋势。

默认地,查询读取的数据页会立刻被移动到新子链表中,也就是这些数据页保存在缓冲池中的时间更长些。例如,mysqldump操作、无where查询条件的查询操作会从磁盘中读取大量的数据保存到缓冲池中,与此同时,同等空间大小的数据页会被淘汰出缓冲池。同理,当预读取的数据页被读取,则会立刻被移动到新子链表的头部,在这种情况下也引起大量的数据页被淘汰出缓冲池。

由以上的分析可知,InnoDB使用LRU算法将不常用的数据页淘汰出缓冲池。

2.1.1.2缓冲池配置

MySQL提供可配置参数,用户能根据实际环境的情况修改配置参数,从而获得更好的性能,从以下几个方面描述可配置参数给用户带来的优势:

  • 应用实际上需要多大内存空间,则配置多大缓冲池,理论上,缓冲池分配的内存空间越大,InnoDB越接近一个内存数据库。也就是,只要内存空间足够大,则加载到缓冲池的数据页永远不会被淘汰。
  • 在64位操作系统中,用户能对缓冲池分区,该性质可以减少在并发环境中资源竞争带来的性能损耗。
  • 用户能指定频繁被访问的数据不被淘汰出缓冲池,即使大量的数据被加载到缓冲池中。
  • 用户能指定什么时候以什么方式加载预读取的数据到缓冲池。
  • 用户能控制什么时候刷数据(已经被更新的脏数据),以及被刷数据量的比率。
  • 用户能指定故障恢复重新加载数据页到缓冲池的策略。

2.1.1.3监控缓冲池

MySQL提供标准化的监控措施对缓冲池的运行数据实行监控与分析,用户可以使用命令SHOW ENGINE INNODB STATUS实时查看其统计分析数据,执行该命令输出如下所示:

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 2198863872

Dictionary memory allocated 776332

Buffer pool size   131072

Free buffers       124908

Database pages     5720

Old database pages 2071

Modified db pages  910

Pending reads 0

Pending writes: LRU 0, flush list 0, single page 0

Pages made young 4, not young 0

0.10 youngs/s, 0.00 non-youngs/s

Pages read 197, created 5523, written 5060

0.00 reads/s, 190.89 creates/s, 244.94 writes/s

Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not

0 / 1000

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read

ahead 0.00/s

LRU len: 5720, unzip_LRU len: 0

I/O sum[0]:cur[0], unzip sum[0]:cur[0]

以下表格对统计分析的各项输出属性实行分析与说明:

项目名称

描述说明

Total memory allocated

缓冲池已申请的总内存空间,单位:字节

Dictionary memory allocated

InnoDB数据字典已申请的总内存空间,单位:字节

Buffer pool size

缓冲池总页数

Free buffers

缓冲池空闲链表的总页数

Database pages

缓冲池LRU链表的总页数

Old database pages

缓冲池LRU旧子链表的总页数

Modified db pages

缓冲池当前已被更新的总页数

Pending reads

等待被读入缓冲池的总页数

Pending writes LRU

等待从缓冲池链表尾部写的总脏页数

Pending writes flush list

执行检查点时等待刷新写的总页数

Pending writes single page

单页等待写的次数

Pages made young

旧子链表中已被移动到新子链表头部的总页数

Pages made not young

旧子链表中未被移动到新子链表的总页数

youngs/s

平均每秒被移动到新子链表头部的总页数

non-youngs/s

平均每秒未被移动到新子链表的总页数

Pages read

从缓冲池中读取的总页数

Pages created

已在缓冲池中创建的总页数

Pages written

从缓冲池中写入的总页数

reads/s

平均每秒从缓冲池中读取的总页数

creates/s

平均每秒在缓冲池中创建的总页数

writes/s

平均每秒从缓冲池中写入的总页数

Buffer pool hit rate

从缓冲池中读取页数与从磁盘中读取页数的命中率

young-making rate

页读取时需要立刻移动到新子链表头部的平均命中率

not (young-making rate)

页读取时不需要立刻移动到新子链表头部的平均命中率

Pages read ahead

平均每秒预读取总页数

Pages evicted without access

平均每次从缓冲池淘汰的总页数

Random read ahead

平均每秒随机预读取总页数

LRU len

LRU链表的总长度

unzip_LRU len

未解压缩的LRU链表的总长度

I/O sum

LRU链表中页数据被访问的总次数

I/O cur

在当前的时间间隔内LRU链表中页数据被访问的总次数

I/O unzip sum

未解压缩LRU链表中页数据被访问的总次数

I/O unzip cur

在当前的时间间隔内未解压缩LRU链表中页数据被访问的总次数

表2 InnoDB缓冲池统计项目

对以上表格的补充说明:

  • youngs/s项目的统计信息是对旧子链表的,是基于数据页被访问的次数,包括一个数据页被多次访问的次数。如果youngs/s项目的统计数非常小,则说明没有发生大范围的表扫描。
  • non-youngs/s项目的统计信息是对旧子链表的,是基于数据页被访问的次数,包括一个数据页被多次访问的次数。如果non-youngs/s项目的统计数非常小,则说明有发生大范围的表扫描,同时,youngs/s项目的统计数变得非常大。
  • young-making项目的统计信息是对LRU链表的,是基于新子链表与旧子链表数据页被访问的次数的总和。但是在新子链表中,只移动离链表头部较远距离的数据页。
  • not (young-making rate)项目的统计信息是对LRU链表的,基于不需要移动到新子链表头部的数据页的访问次数。

(未完待续)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL之InnoDB引擎(一) 的相关文章

  • Java 的 System.arraycopy() 对于小数组有效吗?

    是Java的System arraycopy 对于小数组来说是高效的 或者它是本机方法这一事实是否使其可能比简单的循环和函数调用效率低得多 本机方法是否会因跨越某种 Java 系统桥梁而产生额外的性能开销 稍微扩展一下 Sid 所写的内容
  • 在 Eclipse 中跨文件搜索注释掉的代码

    有没有一种快速方法可以在 Eclipse 中查找 Java 文件中所有注释掉的代码 也许是搜索中的任何选项 或者任何可以执行此操作的附加组件 它应该只能找到被注释掉的代码 而不是普通的注释 在 Eclipse 中 我只是在打开正则表达式复选
  • Spring Rest POST Json RequestBody 不支持内容类型

    当我尝试使用 post 方法发布新对象时 RequestBody 无法识别 contentType Spring 已经配置完毕 POST 可以与其他对象一起使用 但不能与这个特定对象一起使用 org springframework web
  • 使用 Hibernate 或 Spring 打印 DBMS_OUTPUT.put_line

    我想知道 Hibernate 或 Spring 或任何第 3 方库是否提供将 DBMS OUTPUT put line 消息直接打印到 system out 或日志文件的能力 目的是在控制台中同时显示 PLSQL 日志消息和 java 日志
  • 为什么Java HashMap的最大容量是1<<30而不是1<<31?

    Why is the maximum capacity of a Java HashMap 1 lt lt 30 and not 1 lt lt 31 even though the max value of an int is 231 1
  • 寻找 WebElements,最佳实践

    在我们当前的自动化 使用 Selenium WebDriver Java 中 我们使用 FindBy very广泛地 例如 FindBy css a name bcrumb protected List
  • 如何使用 Connector/C++ 更新 MySQL 中的一行值

    我有一个简单的数据库 想要更新一个 int 值 我最初执行一个查询并返回一个 ResultSet sql ResultSet 对于结果集中的每个条目 我想修改表的一个特定列中的值 然后将其写回到数据库 更新该行中的该条目 根据文档 我不清楚
  • 将位于 jar 中的文件读取为 java.io.File 对象

    与此类似的问题已发布 但似乎没有一个答案对我的情况有帮助 我正在编写一个程序包 它使用 Google 的凭据来获取 Google Apps 用户 为此 我使用服务帐户 因此为了检索凭据 我需要提供 除其他外 一个 p12 签名文件 Cred
  • 为什么不能将 String 添加到 List 类型?

    错误 The method add capture 1 of in the type List
  • splitByWholeSeparatorPreserveAllTokens 和 split 之间的区别

    有什么区别StringUtils splitByWholeSeparatorPreserveAllTokens and String split With splitByWholeSeparatorPreserveAllTokens 我们可
  • Stream#limit 返回的元素是否可以少于预期?

    如果流s下面至少有n元素 流在什么情况下sLimit可能少于n元素 如果有的话 Stream sLimit s limit n 提问原因 在这个答案 https stackoverflow com a 28082107 829571 我读到
  • Ubuntu 的打包 - Web 应用程序

    Web 应用程序没有与 C 或类似文件不同的 make 文件 但是 它需要放置在特定的目录中 例如 var www 我是 Linux 打包新手 所以我的问题是 如何将我的应用程序打包到 deb 中 以便在安装时将其放入 etc myprog
  • 在Java中使用==而不是equals来比较不可变对象可以吗

    考虑调用静态工厂方法 valueOf 的两个 Integer 类型的引用 如下所示 Integer a Integer valueOf 10 Integer b Integer valueOf 10 考虑到Integer是不可变的 使用 而
  • 我们可以用java定制一个垃圾收集器吗?

    我们知道java的垃圾收集器是一个低优先级线程 在java中我们可以创建任何具有高优先级的线程 那么是否有可能拥有我们自己定制的具有可变优先级的垃圾收集器线程 我们可以根据内存管理的级别进行设置 有人尝试过吗 如果是的话 您能分享一些关于如
  • Web服务连接超时和请求超时之间的区别

    WebClientTestService service new WebClientTestService int connectionTimeOutInMs 5000 Map
  • JTable中动态加载大量数据

    这是我的问题 我目前有一个 JTable 其中包含 5 000 到超过 200 000 行 你知道我要说什么了 数据已经加载到内存中了 这不是问题 但是如何 我可以创建一个高效的 JTable 以便它只加载以下行 是可见的 并且任何事件仅作
  • spring-boot-starter-web 2.4.4 导入 spring-web 和 spring-webmvc 版本 4.3.12 在 pom 中列为 5.3.5

    我正在使用spring boot starter web我的项目中的版本2 4 4 当我查看其内容时 它清楚地列出了 spring web 和 spring webmvc 5 3 5 版本 但是 由于某种原因 我可以看到这个 spring
  • 在测试期间调用预定方法[重复]

    这个问题在这里已经有答案了 我正在使用 Maven 开发 SpringBoot 应用程序 我有一个班级 Component有方法的注释m与 Scheduled initialDelay 1000 fixedDelay 5000 注解 这里f
  • Java applet 是否会违反同源策略

    我需要请求一些东西并从其他域获取信息 我知道由于同源政策 javascript 无法做到这一点 我的另一个选择是通过我的服务器发出代理请求 我不希望请求来自我的服务器的 IP 也不想为我的服务器创建额外的负载 并且希望客户端这样做 是否可以
  • 将redis数据移至MySQL的更快方法

    我们拥有庞大的购物和产品交易系统 我们在 MySQL 方面遇到了很多问题 因此经过几次研发后 我们计划使用 Redis 并开始将 Redis 集成到我们的系统中 继之前直接访问数据库之后 现在我们已经移动了Redis系统 用户购物车详情 关

随机推荐

  • PAT C入门题目-7-124 天梯赛座位分配 (20 分)(动态内存分配)

    7 124 天梯赛座位分配 20 分 天梯赛每年有大量参赛队员 要保证同一所学校的所有队员都不能相邻 分配座位就成为一件比较麻烦的事情 为此我们制定如下策略 假设某赛场有 N 所学校参赛 第 i 所学校有 M i 支队伍 每队 10 位参赛
  • 【自学Linux】 Linux文件目录结构

    Linux文件目录结构 Linux文件目录结构教程 在 Linux 中 有一个很经典的说法 叫做一切皆文件 因此 我们在系统学习 Linux 之前 首先要了解 Linux 的文件目录结构 Linux 主要的目录有三大类 即根目录 usr 目
  • Tracy vue3 小笔记 1 - 如何使用 VUE, MVC, MVVM, Template, Vue 源码

    Vue Demo code 计数器那么安装和使用Vue这个JavaScript库有哪些方式呢 方式一 在页面中通过CDN的方式来引入 方式二 下载Vue的JavaScript文件 并且自己手动引入 方式三 通过npm包管理工具安装使用它 w
  • 智能输液系统(STM32+ESP8266-01S+阿里云+安卓APP)

    下位机 阿里云 APP 下位机流转上位机
  • 2021-08-19-leetcode-00001

    二分查找 704 给定一个 n 个元素有序的 升序 整型数组 nums 和一个目标值 target 写一个函数搜索 nums 中的 target 如果目标值存在返回下标 否则返回 1 278 你是产品经理 目前正在带领一个团队开发新的产品
  • Linux 学习笔记3 权限管理 定时任务 网络配置 进程、软件包管理

    权限管理 linux组的介绍 在linux中的每个用户必须属于一个组 不能独立于组外 在linux中每个文件有所有者 所在组 其它组的概念 1 所有者 2 所在组 3 其它组 4 改变用户所在的组 文件 目录所有者 一般为文件的创建者谁创建
  • kettle进阶之database join

    前言 这并不是一篇入门教学 且不是一篇高阶教学 仅仅针对kettle的database join 那么问题来了 kettle的database join是什么 简而言之 不同库之间sql语句传值 个人自定义 如有不当 请海涵 案例1 一条数
  • SQL Server 集合处理

    UNION ALL 返回两个结果集中所有的行 返回结果集中会存在重复行 UNION 返回两个结果集中去重的行 返回结果集中无重复行 INTERSECT 返回两个结果集都有的行 返回结果集中无重复行 EXCEPT 返回第一个结果集中有而第二个
  • vuex与生命周期的关系

    vue与生命周期的关系 问题呈现 获取到数据同时保存到vuex中 2 计算属性获取vuex中的值 3 循环输出 4 出现错误 问题解析 如果单独输出item questionSimpleInfo是可以输出整个对象的 但是输出其中某一个字段的
  • 论文阅读-Thinking in Frequency: Face Forgery Detection by Mining Frequency-aware Clues(F3Net基于频率感知线索的人脸)

    一 论文信息 题目 Thinking in Frequency Face Forgery Detection by Mining Frequency aware Clues 基于频率感知线索的人脸伪造检测 作者团队 会议 ECCV 2020
  • Markdown矩阵及公式语法编辑

    Markdown矩阵及公式语法编辑 详见链接 https cloud tencent com developer article 1402840
  • 9. xaml ComboBox控件

    1 运行图像 2 运行源码 a Xaml源码
  • C++中虚函数、虚指针和虚表详解

    关于虚函数的背景知识 用virtual关键字申明的函数叫做虚函数 虚函数肯定是类的成员函数 存在虚函数的类都有一个一维的虚函数表叫做虚表 每一个类的对象都有一个指向虚表开始的虚指针 虚表是和类对应的 虚表指针是和对象对应的 多态性是一个接口
  • Windows CMD 输出文本到文件,不加换行符

    gt test txt set p Hello
  • 共筑安全创新生态,持安科技加入麒麟软件安全生态联盟

    近日 麒麟软件安全生态联盟第二季度工作会议成功举行 零信任办公安全领域明星企业持安科技受邀参会 并参与授牌环节成为麒麟软件安全生态联盟会员单位 麒麟软件安全生态联盟授牌仪式 会上 联盟成员单位围绕操作系统安全事件与漏洞发展趋势 行业应用对操
  • Beego v2.0 编译后无法运行问题

    问题 beego版本 v2 0 1 通过bee pack be GOOS linux 打包后运行可执行程序报错 如下 panic err go command required not found exec go executable fi
  • Vue+Element-ui Table 列求和

    Vue Element ui Table 列求和 Vue代码 求和getSummaries 效果图 Vue代码
  • [GameFramework分析] Log(日志)

    文章目录 使用 分析 Unity脚本 Log LogScriptingDefineSymbols ScriptingDefineSymbols DefaultLogHelper 框架类 GameFrameworkLogLevel GameF
  • graylog日志分析管理系统入门教程

    日志分析系统可以实时收集 分析 监控日志并报警 当然也可以非实时的分析日志 splunk是功能强大且用起来最省心的 但是要收费 免费版有每天500M的限制 超过500M的日志就没法处理了 ELK系统是最常见的 缺点是配置麻烦一些 比较重量级
  • MySQL之InnoDB引擎(一)

    1 InnoDB介绍 InnoDB是一个通用的存储引擎 同时具备高可靠性与高性能的特性 除非用户指定存储引擎的类型 否则其作为MySQL Server的默认存储引擎 使用InnoDB存储引擎的优势包括如下几点 DML操作符合ACID模型 使