InnoDB详解 (1)

news2025/7/12 14:08:56

文章目录

  • 1 InnoDB详解 (1)
    • 1 概念介绍
    • 2 页介绍
      • 1 页内部结构介绍
        • 1 File Header(文件头部)(38字节)
        • 2 File Trailer(文件尾部)(8字节)
        • 3 Free Space (空闲空间)
        • 4 User Records (用户记录)
        • 5 Infimum + Supremum(最小最大记录)
        • 6 Page Directory(页目录)重点
        • 7 Page Header(页面头部)

1 InnoDB详解 (1)

1 概念介绍

聚簇索引:innodb的聚簇索引 根据主键构建索引,B+数的叶子节点存储一条完整的数据。若果创建的表没有主键,会隐式生成一个字段构建B+树。

非聚簇索引:也叫二级索引或辅助索引,只记录主键值和二级索引的值。根据二级索引构建B+数,末尾记录了主键值。

如一个学生表id是主键,包含age,name等字段。创建一个索引 idx_age ,叶子节点记录了age值和该表的主键id的值。此时查询语句select * from student where age >18; 就会走age索引,叶子节点记录了id值,就根据id再回表查询name和其他值。

image-20221222235525194

只有叶子节点存储数据,内节点存储的是叶子节点的主键值页号(在磁盘中的位置)。

页的大小为16K,页中的数据是以单链表的形式构成的。

2 页介绍

由上图可知 页之间 是双向链表连接组成的,页间每条记录是单链表连接的,单链表遍历很慢,在查询数据时,是一条条遍历吗?

image-20221221160644442

1 页内部结构介绍

image-20221223001416561

1 File Header(文件头部)(38字节)

image-20221223001649423

FIL_PAGE_OFFSET(4字节):唯一标识一个页号。

FIL_PAGE_TYPE(2字节):标明该页的类型。类型如下:

FIL_PAGE_PREV(4字节)和FIL_PAGE_NEXT(4字节): 记录上一页下一页地址;页之间是双向链表。

FIL_PAGE_SPACE_OR_CHKSUM(4字节):简单来说就是通过hash来算出一个唯一值,mysql同步数据是以页为单位的,写入数据到磁盘是先计算校验和存到页头和页尾,同步时先向磁盘写入头部校验和,如果突然中断,头尾校验和机会不一样,就可以根据日志进行数据回滚。详细介绍如下

什么是校验和?
就是对于一个很长的字节串来说,我们会通过某种算法来计算一个比较短的值来代表这个很长的字节串,这个比较短的值就称为校验和。
在比较两个很长的字节串之前,先比较这两个长字节串的校验和,如果校验和都不一样,则两个长字节串肯定是不同的,所以省去了直接比较两个比较长的字节串的时间损耗。
文件头部和文件尾部都有属性:FIL_PAGE_SPACE_OR_CHKSUM
作用:
InnoDB存储引擎以页为单位把数据加载到内存中处理,如果该页中的数据在内存中被修改了,那么在修改后的某个时间需要把数据同步到磁盘中。但是在同步了一半的时候断电了,造成了该页传输的不完整。
为了检测一个页是否完整(也就是在同步的时候有没有发生只同步一半的尴尬情况),这时可以通过文件尾的校验和(checksum 值)与文件头的校验和做比对,如果两个值不相等则证明页的传输有问题,需要重新进行传输,否则认为页的传输已经完成。
具体的:
每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的。如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer中的校验和代表着原先的页,二者不同则意味着同步中间出了错。这里,校验方式就是采用 Hash 算法进行校验。

FIL_PAGE_LSN(8字节):页面被最后修改时对应的日志序列位置。

2 File Trailer(文件尾部)(8字节)

  • 前4个字节代表页的校验和:

这个部分是和File Header中的校验和相对应的。

  • 后4个字节代表页面被最后修改时对应的日志序列位置(LSN):

这个部分也是为了校验页的完整性的,如果首部和尾部的LSN值校验不成功的话,就说明同步过程出现了问题。

3 Free Space (空闲空间)

插入记录来来空闲空间申请,然后划分到用户空间,当空闲空间没有时,就要划分到新的页里了。

行格式是啥?下文再详细介绍

我们自己存储的记录会按照指定的行格式存储到User Records部分。但是在一开始生成页的时候,其实并没有User Records这个部分,每当我们插入一条记录,都会从Free Space部分,也就是尚未使用的存储空间中申请一个记录大小的空间划分到User Records部分,当Free Space部分的空间全部被User Records部分替代掉之后,也就意味着这个页使用完了,如果还有新的记录插入的话,就需要去申请新的页了。

img

4 User Records (用户记录)

User Records中的这些记录按照指定的行格式一条一条摆在User Records部分,相互之间形成单链表

5 Infimum + Supremum(最小最大记录)

存入最大最小记录是为了干啥呢?下面会揭晓。

对于一条完整的记录来说,比较记录的大小就是比较主键的大小。比方说我们插入的4行记录的主键值分别是:1、2、3、4,这也就意味着这4条记录是从小到大依次递增。

InnoDB规定的最小记录与最大记录这两条记录的构造十分简单,都是由5字节大小的记录头信息和8字节大小的一个固定的部分组成的,如图所示:

img

这两条记录不是我们自己定义的记录,所以它们并不存放在页的User Records部分,他们被单独放在一个称为Infimum + Supremum的部分,如图所示:

6 Page Directory(页目录)重点

为什么需要页目录?

在页中,记录是以单向链表的形式进行存储的。单向链表的特点就是插入、删除非常方便,但是检索效率不高,最差的情况下需要遍历链表上的所有节点才能完成检索。因此在页结构中专门设计了页目录这个模块,专门给记录做一个目录,通过二分查找法的方式进行检索,提升效率。

需求:根据主键值查找页中的某条记录,如何实现快速查找呢?

SELECT * FROM page_demo WHERE c1 = 17;

方式1:顺序查找

从Infimum记录(最小记录)开始,沿着链表一直往后找。查询效率为O(n)

如果一个页中存储了非常多的记录,这么查找性能很差。

方式2:使用页目录,二分法查找

简单描述一下

将页中的记录按照主键值进行分组,第一组是Infimum最小记录,后面每组是怎么分的呢?

插入数据时连上supremum组成的第二组已经有8条记录了,此时又插入了一条位于最大最小值之间的记录,第二组就会裂开,变成第二组4条记录,第三组5条记录。所以最后一组可能包含1至8条记录。中间组都是4条记录。

每个分组称之为槽(slot)

页目录中记录的是槽中最大记录的地址偏移量

若页 中原来有18条主键从1 递增的记录。

经过分组之后就变成了 1 2345 6789 abcd efghg 5个组 (为了方便表示 采用18进制)槽编号分别为 0 1 2 3 4

原来查询 id = 17 时 需要遍历17次

现在分完组后,采用二分查找

  1. 找到中间槽 (0+ 4)/2 得到2号槽 根据2号槽记录的地址偏移获得值为 9 , 9 <17。
  2. 收缩边界,左边界变为2号槽,中间槽为(2+4)/2 ,得到3号槽,3号槽中地址偏移得到的值为14 ,14 小于 17
  3. 再次二分确定记录在 4号槽中,但是4号槽记录的是最大地址偏移,怎么找到17号呢?单链表不能逆序查找。
  4. 我们可以从3号槽获取地址偏移,顺着该地址遍历,就能找到17号了

image-20221223012653495

中每条记录中有个next_record字段记录的是下一条记录的偏移量,由此构成单链表。

这也解释了为什么要记录最大记录与最小记录,便于分组。

详细描述如下

  1. 将所有的记录分成几个组,这些记录包括最小记录和最大记录,但不包括标记为“已删除”的记录。

  2. 第 1 组,也就是最小记录所在的分组只有 1 个记录;

最后一组,就是最大记录所在的分组,会有 1-8 条记录;

其余的组记录数量在 4-8 条之间。

这样做的好处是,除了第 1 组(最小记录所在组)以外,其余组的记录数会尽量平分。

  1. 在每个组中最后一条记录的头信息中会存储该组一共有多少条记录,作为 n_owned 字段。

  2. 页目录用来存储每组最后一条记录的地址偏移量,这些地址偏移量会按照先后顺序存储起来,每组的地址偏移量也被称之为槽(slot),每个槽相当于指针指向了不同组的最后一个记录。

举例1:

img

举例2:

现在的page_demo表中正常的记录共有6条,InnoDB会把它们分成两组,第一组中只有一个最小记录,第二组中是剩余的5条记录。如下图:

img

从这个图中我们需要注意这么几点:

  • 现在页目录部分中有两个槽,也就意味着我们的记录被分成了两个组,槽1中的值是112,代表最大记录的地址偏移量(就是从页面的0字节开始数,数112个字节);槽0中的值是99,代表最小记录的地址偏移量。

  • 注意最小和最大记录的头信息中的n_owned属性

  • 最小记录的n_owned值为1,这就代表着以最小记录结尾的这个分组中只有1条记录,也就是最小记录本身。

  • 最大记录的n_owned值为5,这就代表着以最大记录结尾的这个分组中只有5条记录,包括最大记录本身还有我们自己插入的4条记录。

用箭头指向的方式替代数字,这样更易于我们理解,修改后如下:

img

再换个角度看一下:(单纯从逻辑上看一下这些记录和页目录的关系)

img

7 Page Header(页面头部)

页面头部包含两个信息

PAGE_DIRECTION:假如新插入的一条记录的主键值比上一条记录的主键值大,我们说这条记录的插入方向是右边,反之则是左边。用来表示最后一条记录插入方向的状态就是PAGE_DIRECTION。

PAGE_N_DIRECTION:假设连续几次插入新记录的方向都是一致的,InnoDB会把沿着同一个方向插入记录的条数记下来,这个条数就用PAGE_N_DIRECTION这个状态表示。当然,如果最后一条记录的插入方向改变了的话,这个状态的值会被清零重新统计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/109424.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

十、51单片机之步进电机

1、什么是步进电机 1.1、外观 1.2、概念 (1)步进电机是一种将电脉冲信号转换成相应角位移或线位移的电动机。每输入一个脉冲信号&#xff0c;转子就转动一个角度或前进一步&#xff0c;其输出的角位移或线位移与输入的脉冲数成正比&#xff0c;转速与脉冲频率成正比。因此&am…

VSCode调试C/C++项目

最近写完了自己的操作系统&#xff0c;深感有一个方便的调试环境是有多么重要&#xff0c;能够提升不少开发效率。恰好最近在的技术交流群里群友在问如何搭建VSCode调试操作系统的环境&#xff0c;刚考完试&#xff0c;就先把这篇VSCode调试C/C的通用教程发出来&#xff0c;而后…

Hadoop综合项目——二手房统计分析(MapReduce篇)

Hadoop综合项目——二手房统计分析&#xff08;MapReduce篇&#xff09; 文章目录Hadoop综合项目——二手房统计分析&#xff08;MapReduce篇&#xff09;0、 写在前面1、MapReduce统计分析1.1 统计四大一线城市房价的最值1.2 按照城市分区统计二手房数量1.3 根据二手房信息发布…

全网首发“Java面试考点大全”,20+互联网公司,应有尽有

受疫情影响&#xff0c;今年似乎给人感觉时间比往年还要流逝得更快。显然&#xff0c;春节一过&#xff0c;我们又将迎来面试旺季金三银四。对于程序员来说&#xff0c;秋招的失利更意味着在金三银四要打一场“硬战”&#xff0c;可又有多少人做好了面试的准备呢&#xff1f;对…

Fabric.js 监听元素相交(重叠)

本文简介 点赞 关注 收藏 学会了 fabric.js 提供了一个方法可以检查对象是否与另一个对象相交&#xff08;也可以叫元素是否重叠&#xff09;。 这个方法叫 intersectsWithObject()。 本文主要想提一下 fabric.js 存在这么一个方便的方法。 检测元素是否相交有什么用呢&am…

【UE4 第一人称射击游戏】04-血溅效果

素材资料地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1epyD62jpOZg-o4NjWEjiyg 密码&#xff1a;jlhr 效果&#xff1a; 步骤&#xff1a; 1.将图片素材导入UE4 2.创建一个控件蓝图&#xff0c;命名为“Damageeffect” 双击打开“Damageeffect”&#xff0…

【关于时间序列的ML】项目 6 :机器学习中使用 LSTM 的时间序列

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

现在转行学python,前景和优势有哪些?

正所谓“男怕入错行&#xff0c;女怕嫁错郎”&#xff0c;可想而知进入一个正确的行业有多重要。 IT行业的高薪吸引着越来越多转行“入坑”&#xff0c;python作为目前的大势&#xff0c;是很多人转行的首选。 为什么这么多的人都想转行学习python&#xff0c;python有哪些前…

【架构师(第四十九篇)】 服务端开发之认识 Docker-compose

Docker-compose 介绍 通过一个配置文件&#xff0c;可以让系统一键启动所有的运行环境&#xff0c;nodejs&#xff0c;mysql&#xff0c;redis&#xff0c;mongodb 等。 如果开发环境需要多个服务&#xff0c;就需要启动多个 Docker 容器。 要连通多个 Docker 容器&#xf…

转行程序员,如何挑选既高薪又适合的编程语言?

“你为什么要学这个编程语言&#xff1f;” 很多人面对这个问题时&#xff0c;都回答不上来&#xff0c;大部分都只是看到了表象&#xff0c;或是脑子一热&#xff0c;随意给自己选了一个。事实上自己对这个编程语言的特性和市场现状并不了解&#xff0c;甚至都不知道这个语言到…

关于为什么要做量化白皮书这件事

我们一直想着再为行业做点什么 是从什么时候开始 在心里埋下了种子呢 许是从有人说“高频量化不除&#xff0c;市场再无宁日”的时候 是从中国基金报房佩燕老师写“这锅我们不背“的时候 是从部分量化私募主动站出来说话的时候 现今的互联网时代信息太繁杂 有时可以不用太…

ETCD的创建

一&#xff1a; 好原文链接&#xff1a; 搭建高可用Kubernetes集群之etcd v3.4.13集群搭建(一&#xff09; - 人艰不拆_zmc - 博客园1. etcd 简介 coreos 开发的分布式服务系统&#xff0c;内部采用 raft 协议作为一致性算法。作为服务发现系统&#xff0c;有以下的特点&#x…

【Vue】源码—虚拟DOM和diff算法

1.理解虚拟DOM和diff算法 1.1什么是虚拟DOM&#xff1f; 从本质上来说&#xff0c;虚拟DOM是一个JavaScript对象&#xff0c;通过对象的方式来表示DOM结构。将页面状态抽象为JS对象的形式&#xff0c;配合不同的渲染工具&#xff0c;使跨平台渲染成为可能。虚拟DOM是DOM的抽象…

【Python百日进阶-数据分析】Day136 - plotly旭日图:px.sunburst()实例

文章目录四、实例4.1 带有 plotly.express 的旭日图4.1.1 基础旭日图4.1.2 带有 plotly.express 的矩形 DataFrame 的旭日形4.1.3 改变path顺序&#xff0c;从而改变父子关系4.1.4 在 px.sunburst 中具有连续颜色参数的矩形 DataFrame 的 Sunburst4.1.5 在 px.sunburst 中具有离…

20岁电竞选手自学编程转行程序员,轻松拿下大厂offer

话说 人与人之间的差距 貌似挺小的 毕竟 不管是大佬还是我们 都是两只眼睛、一个鼻子、一张嘴 不多不少 醒醒&#xff0c;别睡了 人和人的差距是很大的&#xff01; 同样身为互联网冲浪选手 别人干啥啥都行 你却只会在评论区扣“牛X” #01 在多数人的认知里 电竞选…

校园网上报修系统/宿舍报修系统的设计与实现

摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;校园网上报修系统当然也不能排除在外&#xff0c;从报修信息的统计和分析&#xff0c;在过程中会产生大量的、各种各样的数…

Java Number Math 类

一般地&#xff0c;当需要使用数字的时候&#xff0c;我们通常使用内置数据类型&#xff0c;如&#xff1a;byte、int、long、double 等。 实例 int a 5000; float b 13.65f; byte c 0x4a; 然而&#xff0c;在实际开发过程中&#xff0c;我们经常会遇到需要使用对象&…

Java -- OSS对象存储服务(Object Storage Service,简称 OSS)文件服务器

一个成熟的技术架构要有一定的分离性&#xff0c; 平台级的产品一般会这么分&#xff1a;应用服务器、数据库服务器、文件服务器。一般文件、数据库、应用服务器&#xff0c;都应该做逻辑和物理的分离。 以前我们想要做文件上传可能要自己去搭建一个专门的服务器&#xff0c;然…

【Oracle】Oracle学习笔记

【Oracle】Oracle学习笔记 目录【Oracle】Oracle学习笔记P1、Oracle数据库的安装和配置P2、Oracle数据库管理P3-0、初步SQLP3-1、基本SQL SELECT语句课程学习链接&#xff1a; 【尚硅谷】Oracle数据库全套教程&#xff0c;oracle从安装到实战应用 P1、Oracle数据库的安装和配置…

学python以后做什么工作

python是一门很好的编程语言&#xff0c;很多人都在学&#xff0c;那么学完python以后能做什么工作呢&#xff1f;下面小编给大家总结一下。 软件开发&#xff0c;用python做软件是很多人正在从事的工作&#xff0c;不管是B/S软件&#xff0c;还是C/S软件&#xff0c;都能做。…