【MySQL】好好学习一下InnoDB中的页

文章目录

  • 一. 前言
  • 二. 从宏观层面看页
  • 三. 页的基本内容
    • 3.1 页的数据结构
    • 3.2 用户空间内的数据行结构
    • 3.3 页目录
  • 四. 问题集
    • 4.1 索引 和 数据页 有什么区别
    • 4.2 页的大小是什么决定的
    • 4.3 页的大小对哪些情况有影响
    • 4.4 一般情况下说的链表有哪几个
    • 4.5 如果页的空间满了怎么办
    • 4.6 如果页的空间空了怎么办
    • 4.7 删除的数据何时被清理
    • 4.8 数据页和B+树及索引的关系
  • 总结
  • 附录
  • 参考文档

一. 前言

周末没啥计划,把大佬的<MySQL是怎样运行的>又翻了出来,重新学习一下页的概念。
页这个东西,看起来不怎么显眼,但是深层的东西都会碰到他,又爱又恨,逼着人必须弄懂。

二. 从宏观层面看页

高并发里面有一种提高性能的思路是 :通过批处理一次性处理大量数据,避免频繁的网络流量和IO。

MySQL 的页就是基于这种概念,磁盘是存放数据的载体,而数据处理会发生了内存中,所以流程大致分为:

  • S1 : 首先对数据进行切分,划分成若干页
  • S2 : 每次读取的时候,都直接把一整页读取到内存中
  • S3 : 外部读取的时候,直接对内存中的数据进行读取和操作
  • S4 : 如果发生了修改操作,需要把内存的内容刷新到磁盘上

页的好处

这里比较模糊的是为什么要衍生出一个页,而不是通过行级别进行处理。

  • 首先解决的就是 IO 问题,当然如果说每个页只读一条,那么这种就不算优势,但是我们大批量读取的时候,往往是查询连续的数据 , 相对而言取舍后,效率就更高了。
  • 避免碎片化,行的级别太低了,大小也不同,使用行的时候,存储空间不便于分配
  • 提高并发和锁,可以通过控制事务到一个页里面,减少事务的粒度
  • 提高维护性和通用性 ,当发生重整时,页的处理会更简单

三. 页的基本内容

页的概念与索引关联的概中主要包括 :

  • 页 (Page): 页是数据存储的基本单位,是一个固定大小的数据块,通常是16K
  • 行 (Row): 行是数据库中的基本数据单位 ,代表表中的一个记录
  • 分组(Group):将一个页里面除了删除的记录进行逻辑划分,取每组最后一条记录作为偏移量标志位
  • 槽(Slot):每个分组的最后一条数据会在页目录里面作为一个指针存在,这个指针就是一个槽
    页目录 (Page Directory):用来管理数据页的一种数据结构,目录内记录了指针,索引等位置信息

3.1 页的数据结构

在这里插入图片描述

  • File Header 和 Page Header 包含了该页的基础属性和状态信息等
  • Infimum / Supremum 是虚拟的行记录,用于限定记录的边界,他们都是虚拟的,不表示任何存在
  • Infimum 标识比该页任何值都要小的值
  • Supremum 标识比该页任何值都要大的值
  • 用户记录和空闲记录是实际的存储空间,随着插入数据空闲空间会越来越小
  • 页面目录用来存储记录的相对位置,通过稀疏目录的方式加快了查询的数据
  • File Trailer 目的是为了保证数据的完整性,其中会存放一个校验和保证数据是正确的

插入数据带来的结构变化

3.2 用户空间内的数据行结构

在这里插入图片描述

其中主要的参数是 :

  • n_owned:当前记录拥有的记录数 ,通过该数据来确定每组数据的大小
  • heap_no:当前记录在堆的位置,最小和最大的heap_no 分别是 0,1 ,标识在最上面
  • next_record:下一记录的相对位置 , 用于保证数据成一个链表结构

3.3 页目录

我们或多或少都接触过数组或者集合,对于数组的查询方式有很多,正序或者逆序,或者效率更高的二分法
前提 : MySQL 的数据按照行记录进行存储,在一个表中,行的数据是有序的
目录 :但是不论多么优良的算法,在大数据量的场景下,还是会有很高的性能损耗,而 MySQL 为了解决这种场景,采取的是目录的方式。 目录中通过槽和分组,得到了一个数据的精简模型,通过精简的数据快速查询对应的分组,再在分组里面进行循环查找

槽和分组

有个资料里面说的是一个数据行就对应一个槽,也有说多个记录一个槽,我这里倾向于后一种说法,即稀疏目录。
页目录存放了记录的相对位置,每个相对位置即为一个槽,在InnoDB 里面是使用稀疏目录 (sparse directory), 即一个槽会属于多个记录 (4-8条)

在这里插入图片描述

  • 最小记录的条数是1

  • 最大记录所在分组的记录数是1-8

  • 其他分组在 4-8之间

  • 指向原理

    • 查询数据时,首先通过二分法在页目录中进行查询
    • 当查询到分组范围后,再通过分组里面的 next_record 查询具体的数据

四. 问题集

4.1 索引 和 数据页 有什么区别

  • 两者不是同一个东西,存储的数据和结构都不同
  • 在索引中,每一个 B+树节点对应一个索引页,一个索引页中存储索引键值和指向指针
  • 数据查询时,通过根索引页开始,遍历索引树,从而拿到指向数据行的指针
  • InnoDB 会通过索引中的数据行指针定位到数据页 (直接通过物理地址指向槽号)

除了这些页,InnoDB 中还有存放表空间头部信息的页,Buffer 页等。

4.2 页的大小是什么决定的

  • 页的大小是由创建数据库表时指定的存储参数 innodb_page_size 决定的
  • 参数一旦设置就不能更改,不然就得刷页里面大量的数据

CREATE TABLE my_table (...) ENGINE = InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 PAGE_COMPRESSED=1 PAGE_SIZE=64K;

4.3 页的大小对哪些情况有影响

  • 索引效率 :前面说了,索引过程中会通过每页的最大最小进行快速匹配,而较大的页一定程度上会使相同数据量情况下拥有更少的页,从而降低索引节点的数量,索引树高度也因此降低。查询效率会有所提高
  • 内存占用 :较大的页会在内存中占用更多的空间。因为读取时,每次都是读取一整页,所以内存每次读取得更多。
  • 其他硬件影响 :更大的页会影响磁盘IO和CPU,IOPS 方面都会带来更多的压力

总结 :提高效率,但是增加了系统负载。

4.4 一般情况下说的链表有哪几个

一个列里面的数据行之间通过 next_record 形成的单向链表

上文说到了每个数据行上面会有个 next_record 参数,该参数记录了真实数据达到下一条记录的真实数据的偏移量,这里有几点值得注意 :

  • 这里的顺序不是插入数据,而是主键值由小到大的顺序
  • 上一条指向的是下一条的value的位置,而不是 Header 头的位置
    在这里插入图片描述

不同数据页之间组成的双向链表

上面的结构图看过了,每个页里面都会包含 File Header 和 Page Header 两个对象。

  • Page Header : 记录当前页的状态信息和规则,例如槽数,记录数,剩余空间数等等
  • File Header : 记录当前页的标准信息,包括页的编号,页所在的表空间,上一页页号和下一页页号

而**双向成方式不言而喻,都知道上页 (FIL_PAGE_PREV) 和 下页(FIL_PAGE_NEXT)的页号了,那访问完全没问题了 , 由于都只存了上一个和下一个,也就形成了标准的链表结构。
补充 : 上面看到的这种通常是指 LRU 链表,还有一个双向链表是 Flush List (刷新链表),这个链表是在数据页发生修改后,使用刷新链表可以让数据按照一定的顺序刷新到磁盘上

4.5 如果页的空间满了怎么办

  • 首先,页的的大小是在存储引擎创建的时候就确定了,所以空间固定。
  • 其次页内数据是按照主键进行排序,所以这个时候插入铁定空间超了

在这种场景下,会触发页分裂 ,此时 InnoDB 会执行下列操作 :

  • S1 : 创建新的数据页
  • S2 : 按照排序方式将部分数据迁移到新页
  • S3 : 更新上下页关系和对应的索引关系

这里由于页是双向链表进行的关联,所以插入并不会对数据结构进行大的破坏,只需要对应的上下页进行更新就行了。

4.6 如果页的空间空了怎么办

既然会有页分裂,那就有可能会出现分裂的页不均衡的情况,长时间下去,就会形成很多空闲块,这样的结构也是不合理的,不仅会占用不必要的空间,还会导致查询性能降低。

为了避免这些问题,InnoDB 会有页合并的功能 , 原理和上面的类型。相邻页尝试合并,然后重新更新引用和索引。

4.7 删除的数据何时被清理

之前看到了数据被删除后,其目录数据里面的 delete_mask 会被置为已删除。

此时的数据处在逻辑删除的状态,通过上面说的 next_record (下一记录的相对位置)指向后续存在的正常数据。

这样做的目的主要是避免碎片,提高删除的性能(只需要修改标识和引用),同时保证了删除的事务。

但是长此以往就会有大量的删除数据占用空间,为了避免这种情况,InnoDB 会定期的进行清理,同时重新整理数据页。

4.8 数据页和B+树及索引的关系

  • 数据页是为了存储数据行的,存放的是二进制数据,通常数据行按照主键的顺序存放

  • B+树是一种数据结构,也是索引的结构,B+树结构让索引更加有效和便于管理

  • 索引中的B+树叶子节点存储了索引条目,每个条目对应一个数据行的物理指针(通常是数据行的槽号)

    • 当获得槽号后,就直接通过槽号读取想要的数据,并且返回

页和索引是相辅相成的,如果没有索引,页就需要在单向链表里面向下寻找,直到找到对应的数据

总结

页是存储的基础,也是索引的基础,了解了页后面就可以深入的了解索引了。

这一块没了解太深,毕竟这东西其实我应用的场景几乎没有,主要是不弄清楚后面读起来很难受。

尽量做到了自己去输出东西,整理了一些问题,但是毕竟站在别人修好的路上面,有些东西不能保证一定是对的,也有可能是我理解有误,如果有问题建议去看原文或者官方文档。

附录

头部信息对于我们日常业务中几乎是没太大用的,这里只记录几个我认为和上文有一定关联的参数 :

  • 页头部信息

    • PAGE_N_DIR_SLOTS : 页目录中的槽数量
    • PAGE_N_HEAP : 本页中的记录数量
    • PAGE_GARBAGE : 已删除记录中的字节数
    • PAGE_LAST_INSERT :最后插入记录的位置
    • PAGE_DIRECTION :记录插入的方向
    • PAGE_N_RECS : 该页中记录的数量
    • PAGE_LEVEL : 当前页在 B+树中所处的层级
    • PAGE_INDEX_ID : 索引ID
  • 文件头部信息

    • FIL_PAGE_OFFSET : 页号
    • FIL_PAGE_PREV : 上一个页的页号
    • FIL_PAGE_NEXT : 下一个页的页号
    • FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID : 页属于哪个表空间

参考文档

  • 小册 : MySQL是怎样运行的

  • MySQL 技术内幕

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

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

相关文章

CentOS 7 安装MySQL8.0.33

一、查看 CentOS 版本 要查看当前 CentOS 版本&#xff0c;你可以执行以下命令&#xff1a; cat /etc/centos-release 该命令将显示当前 CentOS 的版本信息&#xff0c;例如&#xff1a; CentOS Linux release 7.9.2009 (Core) 在这个示例中&#xff0c;CentOS 版本为 7.…

【Python从入门到进阶】32、bs4的基本使用

接上篇《31、使用JsonPath解析淘票票网站地区接口数据》 上一篇我们介绍了如何使用JSONPath来解析淘票票网站的地区接口数据&#xff0c;本篇我们来学习BeautifulSoup的基本概念&#xff0c;以及bs4的基本使用。 一、BeautifulSoup简介 1、bs4基本概念 BeautifulSoup是一个P…

KUST_LI计算机视觉实验室服务器安装与管理

第一步&#xff1a;安装 Linux-Ubuntu系统 系统语言设置为英文 ENGLISH&#xff0c;防止系统 BUG&#xff1b;选择-清除整个磁盘并安装系统&#xff1b;设置用户名和密码&#xff0c;实验室统一其余全部默认设置 开机后设置磁盘挂载 在系统设置中找到 desk 打开&#xff0c;…

动物IT

动物是地球上最丰富和多样化的生物群体之一。它们包括鱼类、鸟类、爬行动物、两栖动物和哺乳动物等各种类型。动物在地球上有着不同的生态角色和生活习性。 动物对于维持生态平衡和生态系统的稳定性至关重要。它们在食物链中扮演着重要的角色&#xff0c;通过捕食和被捕食来保…

轻松搭建书店小程序

在现今数字化时代&#xff0c;拥有一个自己的小程序成为了许多企业和个人的追求。而对于书店经营者来说&#xff0c;拥有一个能够提供在线购书服务的小程序将有助于吸引更多的读者&#xff0c;并提升销售额。本文将为您介绍如何轻松搭建书店小程序&#xff0c;并将其成功上线。…

第7步---MySQL的视图操作和

第7步---MySQL的视图操作 虚拟表。保存的只是视图的定义。不存放真实的数据&#xff0c;数据还是在原先的表中。 好处是方便和简化代码以及安全。 1.视图创建 数据准备 -- 创建表的测试数据 create table dept(deptno int primary key,dname varchar(20),loc varchar(20) ); …

Android学习之路(8) Activity

本节引言&#xff1a; 本节开始讲解Android的四大组件之一的Activity(活动)&#xff0c;先来看下官方对于Activity的介绍&#xff1a; 移动应用体验与桌面体验的不同之处在于&#xff0c;用户与应用的互动并不总是在同一位置开始&#xff0c;而是经常以不确定的方式开始。例如&…

项目管理实战笔记1:项目管理常识

序 看了下极客时间的《项目管理实战》&#xff0c;觉得跟之前学习PMP的标准资料还是有所侧重。重新整理下&#xff0c;相比书上繁杂的知识&#xff0c;这个更通俗易懂。 1 角色转换&#xff1a;三大误区 误区1&#xff1a;事必躬亲 自己做事情是可控的&#xff0c;做项目依赖…

【脚踢数据结构】图(纯享版)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;软件配置等领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff01;送给自己和读者的…

Python Django 模型概述与应用

今天来为大家介绍 Django 框架的模型部分&#xff0c;模型是真实数据的简单明确的描述&#xff0c;它包含了储存的数据所必要的字段和行为&#xff0c;Django 遵循 DRY Principle 。它的目标是你只需要定义数据模型&#xff0c;然后其它的杂七杂八代码你都不用关心&#xff0c;…

“Spring管理JavaBean的过程及Bean的生命周期“

目录 引言1.弹簧容器2. Bean的生命周期2.1 配置javaBean2.2. 解析Bean的定义2.3 检查是否需要添加自己的功能2.4 初始化2.5 实现Aware接口2.6 扩展2.7. 销毁 3. 单例模式和原型模式3.1. 单例模式3.2. 原型模式 4. 总结 引言 Spring框架是一个非常流行的Java应用程序框架&#…

【前端】快速掌握HTML+CSS核心知识点

文章目录 1.HTML核心基础知识1.1.编写第一个HTML网页1.2.超链接a标签和路径1.3.图像img标签的用法1.4.表格table标签用法1.5.列表ul、ol、dl标签用法1.6.表单form标签用法1.7.区块标签和行内标签用法 2.CSS核心基础知识2.1.CSS标签选择器viewport布局2.2.CSS样式的几种写法2.3.…

【ES6】—解构赋值

一、定义 解构赋值&#xff1a;解构赋值就是一种模式的匹配&#xff0c;只要等号两边的模式完全相同的&#xff0c;那么左边的变量就会被赋值对应右边的值 二、数组的解构赋值 PS&#xff1a;数组解构赋值时&#xff0c;是通过索引的唯一性赋值的 1. 一维数组解构赋值 (1)…

大数据从入门到放弃——浅谈数据架构的前世今生

文章目录 1. 背景2. 数据的定义及分类2.1 数据的定义2.2 数据的分类2.3 数据和信息的区别 3. 数据的作用4. 数据的那些美好时代4.1 人脑时代4.2 文件时代4.3 数据库时代4.3.1 大服务器时代4.3.2 读写分离时代4.4 数据库的分布式时代4.5 云端时代 5. 数据的未来 1. 背景 随着云时…

自学C#,要懂得善用MSDN

很多初学者学习编程&#xff0c;都会通过看别人写的教程、或者录制的视频&#xff0c;来学习。 这是一个非常好的途径&#xff0c;因为这个是非常高效的。 但是这样&#xff0c;存在两个问题&#xff1a; 1、教程不够全面&#xff1a;任何再好的教程&#xff0c;都无法囊括所…

【C++_primary】类和对象 —— 类

类 ~ ~ ~ 一、面向过程和面向对象初步认识a. 面向过程编程b. 面向对象编程例如&#xff1a;无人机送货系统1、面向过程编程方式2、面向对象编程方式 二、类的引入1、定义类的关键字2、栈的手动实现a. C语言实现栈b. C实现栈 三、类的定义类的两种定义方式&#xff1a; 四、类的…

【Go】锁相关

文章目录 Mutex锁mutex源码分析LockUnLock mutex两种运行模式mutex normal 正常模式自旋 mutex starvation 饥饿模式 锁的底层实现类型 RWMutexRWMutex 实现其他共享内存线程安全的方式 思考如何设计一个并发更高的锁&#xff1f; Mutex锁 mutex源码分析 Locker接口&#xff…

【python知识点】锦集

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/132368704 出自【进步*于辰的博客】 相关博文&#xff1a;【python细节、经验】锦集。 注&#…

MyBatis入门配置及CURD实现

目录 一、MyBatis简介 1. 什么是 MyBatis ? 2. MyBatis的特性 3. 什么是持久层框架&#xff1f; 二、MyBatis环境配置 2.1 创建maven工程 2.2 导入相关pom依赖 2.3 导入jdbc配置文件 2.4 Mybatis相关插件安装 3.5 Mybatis-cfg.xml 核心配置 2.6 引入Log4j2日志文件…

Vue2-配置脚手架、分析脚手架、render函数、ref属性、props配置项、mixin配置项、scoped样式、插件

&#x1f954;:总有一段付出了没有回报的日子 是在扎根 更多Vue知识请点击——Vue.js VUE2-Day6 配置脚手架脚手架结构render函数vue.js与vue.runtime.xxx.js的区别引入render函数为什么要引入残缺的vue呢&#xff1f; 脚手架默认配置ref属性props配置项传递数据接收数据注意点…