IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> mysql——页 -> 正文阅读

[大数据]mysql——页

1.概念

  • 因为 IO操作是很耗费性能的,为了避免一条一条读取磁盘数据,InnoDB采取页的方式,作为磁盘和内存之间交互的基本单位。查询一条数据的时候会把该条数据所在的页全部加载进内存里,以便提高后续查询效率。(存储数据的时候一定会根据主键进行排序,所以id为1,2,3,4,5的数据会在同一页中。)
  • 一个页的大小一般是16KB。
  • InnoDB为了不同的目的而设计了多种不同类型的页,比如:存放表空间头部信息的页、存
    放undo日志信息的页等等。我们把存放表中数据记录的页,称为索引页or数据页。我们主要关注的是索引页(数据页)。

2.页的结构

页的结构

? ? ? ? ?如图所示,页主要包括File Header、Page Header、Infimum+Supremum、User Records、Free Space、Page Directory以及File Trailer

其中:

? ? ? ? File Header:文件头 存储页的通用信息 页跟页之间的双向关联,指针等

????????Page Header:页头 存储数据页专有的信息?

????????Infimum+Supremum:页中的最小和最大记录 表中的数据都会最小记录大,比最大记录小,相当于数学中的-∞、+∞的概念。

????????User Records:用户记录 存放用户记录,因为最小最大记录不是用户主动去存储的,所以为了方便管理,把最小和最大记录单独进行管理,

????????Free Space:空闲空间 与User Records是互斥的关系,主要用来记录当前页的剩余空间大小

????????Page Directory:目录,存储记录在页中的相对位置,为了加快查找,能够查询到记录所在的组

????????File Trailer:文件尾 校验页是否完整

3.页中存储数据的流程

页中存储数据的流程

  • ?开始的时候是没有User Records的,当插入数据的时候,会向Free Space申请空间
  • 插入数据,此时User Records会逐渐变大,而Free Space会逐渐变小
  • 当数据正好满了的时候,Free Space会变为0,不过一般情况下,不会这么凑巧,比如,新插入记录大小为30B,而Free Space只有10B,此时会重新申请一个页存储该条记录,这个10B的Free Space就会剩下在当前页中。

4.记录的头信息

  • 我们在mysql中最常用的行存储格式是compact 行格式

记录的真实数据(insert语句中插入的内容):

  • 主键列的值:存放主键的值
  • 两个隐藏列:
    • trx_id列的值:事务id
    • roll_pointer列的值:回滚的指针,指向回滚的内容?
  • a列/b列的值:除主键外依次插入值

记录的额外信息:

  • 变长字段长度列表:变长字段指varchar等字符串类型,在存储的过程中,int,number都有固定大小的存储,字符串类型传入值多大就会存储多少,这样的目的是节省空间
  • NULL值列表:储存空值列表
  • 记录头信息:(最重要)
    • 预留位1:无需关心
    • 预留位2:无需关心
    • deleted_flag:删除标志,0未删除,1已删除
    • min_rec_flag:目录项,只会在B+树的非叶子节点最小的目录项中添加这个标记

? ? ? ? ? ? ? ? 目录项的作用是快速找到对应的页,在record_type的类型1中使用。

    • n_owned:记录当前组里的数量,此位置只会在主键最大的记录中维护
    • heap_no:堆号,在页面堆(innodb中数据连续排列,这种结构称为heap)中,记录的相对位置,根据heap_no可以直接找到该条记录所在的位置,序号从2开始排列,heap_no为0的是Infimum,为1的是Supremum,分配之后该值就不会发生变化(特别是删除中)。
    • record_type:记录类型,4种类型:
      • 0- 普通记录(用户插入的记录)
      • 1- B+树中非叶子节点的目录项记录(根据目录项可快速找到对应的记录)
      • 2-?Infimum
      • 3-?Supremum
    • next_record:记录的是当前记录的next_record与下一条记录的next_record之间的偏移量 。 指向下一个记录,记录下一个记录的信息,此处需要注意的是,这里指向的是记录的真实数据的主键列的值,而不是变长字段长度列表,因为这样方便查找,想查下一条记录的额外信息只需要指向下一条记录再往前查询即可,查询真实信息,往后查询即可

5.删除记录操作对next_record的影响

? ? ? ? 记录在页中是根据主键从小到大顺序排列的

? ? ? ? 记录之间是单向链表,优势是存储空间小,缺点是不能往前遍历

删除记录操作对next_record的影响

?由上图可以看出:

  • 被删除的记录的deleted_flag 从0变成1
  • 被删除记录的上一条记录的next_record指向被删除记录的下一条记录;
  • supremum中n_owned数量由原来的5变成4(当前分组中)

?????????需要注意的是,图中显示的是虚线,实际上这条数据并没有被删除,这就产生了垃圾链,原因是为了复用空间,如果将这条数据直接删除的话,会出现如下问题:记录是顺序存储的,删除之后会出现碎片空间,如果不处理,会造成资源浪费,如果处理,后续的记录需要向前移动,会产生性能损耗;如果只是修改了记录的状态,后续恢复时只需要,将上述步骤进行反向操作即可,此时避免了分配空间。

6. Page Directory(页目录)— — 记录在页中的展现

? ? ? ? 作用是在页中直接定位记录,提高查找性能

分组规则:????????

  • Infimum单独一组
  • Supremum组允许出现1~8条记录
  • 普通组4~8条记录
  • 只统计非删除记录
Page Directory

?????????上图的分组即为满足分组条件之后分组情况,此时分组1中只有Infimum,分组2中有5条记录,其中最大的是Supremum(依照主键排列,而Supremum是最大的),上图中的Slot即为槽位,也就是page Directory,Slot指向组中最大的那条记录的next_record。
根据分组的规则,当没有数据的时候默认只有两个分组,Infimum和Supremum;新插入数据的时候,会放到Supremum分组中,当Supremum分组的记录已经有8条(含Supremum记录),再插入一条时,会进行组分裂,开新的组,Supremum会分出4条记录给新的组,此时三个分组的情况是 1.4.4,然后再将新的记录插入。

????????查询:先查询page Directory,使用二分法查找,查到对应的slot即可指定到对应的组,由于组中都是单向链表形式,所以从组中的第一个元素,依次遍历查找即可,因为组中的记录数不多,所以此时效率也不会损耗很多。

7.页满后的插入操作

?

页满后的插入操作

?????????插入的时候指定id乱序插入,不使用order by查询出来的结果依然是根据id排序的,存储的时候就是根据主键排序。

????????如果页已经满了,此时插入新的记录时,会申请一个新的页,此时根据主键排序,进行记录迁移,上图中插入的记录比已有的页中的最大用户记录小,此时会将原id为10的记录迁移到新的页中,而将新插入的id为7的记录插入到原10那个位置。?

????????所以开发过程中在设计表时需要有一个id,设置自增,这样就可以避免因为主键排序导致的记录迁移,从而规避不必要的性能消耗。??

????????主键自增有一个auto_increment锁,在单体的时候可以保证id唯一,但是分布式部署的时候,多台mysql没法保证id唯一,此时可以使用雪花算法生成唯一id来标记数据唯一,不同库的id相同也没所谓。?

? ? ? ? ?在进行记录迁移的过程中,heap_no也不会发生变化,查找记录根据next_record来查找,不根据heap_no

?

**************此文章只是本人学习过程中的学习笔记,不做其他用途,如果有其他意见,欢迎一起讨论,谢谢,侵删*************************

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 11:51:37  更:2021-10-08 11:52:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:55:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码