Mysql数据读取方式以及InnoDb页存储

本文内容出自:Mysql是怎样运行的:从根上理解Mysql,有需要学习翻阅的同学自定百度查找。文章只做个人阅读总结。写错了可以指出来,如果你骂我,那我就喷你。

Mysql读取数据方式

将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InooDB中页的大小为16KB,一般情况下一次最少读取16KB到内存中并刷新到磁盘。(1页中至少存放两行记录)

Mysql行格式

mysql表中行存储数据分四种:Compact、Redundant、Dynamic和Compressed行格式。

Compact

在这里插入图片描述

Redundant

在这里插入图片描述

Dynamic和Compressed行格式

存储结构类似于compact格式,但是对于处理行溢出(当一个字段存储长度过大时,会发生行溢出)不同。compact会存储字符串的前768个字节,记录其他信息会存储其他页的地址;它们则是将所有字节存储到其他页,并记录真实数据存储在其他页面的地址。

InnoDb页的存储

InnoDb页结构如下所示;数据被存储user Records中,但是在开始时并没有该空间,只有当插入时,会从Free Space中申请空间分到User Space。当Free Space使用完成后表示该页使用完成,继续申请新页。
在这里插入图片描述

当数据被存入时,对应存储的每条数据结构如下

在这里插入图片描述

其中记录头信息结构如下所示

在这里插入图片描述

delete_mask

当前记录是否被删除,占用1个二进制位,值为0的时候代表记录并没有被删除,为1的时候代表记录被删除掉了。这些被删除的记录不是被立即删除,移除他们需要重新排序消耗性能。所以被标记删除的记录会组成个垃圾链表,占用的空间叫可重用空间。之后有新纪录插入,会进行覆盖。

heap_no

记录当前在本页的位置,从2开始。0和1为自动加入的伪记录数据,不占用User Records。分别代表最大记录和最小记录(根据主键比较大小)

record_type

当前记录属性,0表示普通记录,1表示B+树非叶节点记录,2表示最小记录,3表示最大记录。我们自己插入的记录就是普通记录,它们的record_type值都是0,而最小记录和最大记录的record_type值分别为2和3。

next_record

表示从当前记录的真实数据到下一条记录的真实数据的地址偏移量。下一条地址不是按照插入顺序,而是按照主键由小到大的记录。规定最小记录的下一条记录就是本页最小的用户记录,本页中主键最大的记录的下一条记录地址就是最大记录。最大记录值为0,代表没有下一条记录。记录按照主键的大小形成单链表。结构如图所示
在这里插入图片描述

当删除一条操作,netxt_reord变换方式为:
1.delete_mask值设置为1
2.被删除记录next_record值为0
3.删除的上一条数据next_reord指向下一条
4.n_owned值变小(n_owned在下文说)
不论我们怎么对页中的记录做增删改操作,InnoDB始终会维护一条记录的单链表,链表中的各个节点是按照主键值由小到大的顺序连接起来的。

在这里插入图片描述

页目录(Page Directory)

**规定:
	1.初始情况下一个数据页里只有最小记录和最大记录两条记录,它们分属于两个分组。之后每插入一条记录,都会从页目录中找到主键值比本记录的主键值大并且差值最小的槽,然后把该槽对应的记录的n_owned值加1,表示本组内又添加了一条记录,直到该组中的记录数等于8个。
	2.在一个组中的记录数等于8个后再插入一条记录时,会将组中的记录拆分成两个组,一个组中4条记录,另一个5条记录。这个过程会在页目录中新增一个槽来记录这个新增分组中最大的那条记录的偏移量。
InnoDB会为把页中的记录划分为若干个组,每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中,在一个数据页中查找数据分两部分:通过二分法查找记录所在的槽;通过记录的next_record属性遍历该所在组的记录

	制作过程:
	1. 将所有正常的记录(包括最大和最小记录,不包括标记为已删除的记录)划分为几个组。
	2. 每个组的最后一条记录(也就是组内最大的那条记录)的头信息中的n_owned属性表示该记录拥有多少条记录,也就是该组内共有几条记录。
	3. 将每个组的最后一条记录的地址偏移量单独提取出来按顺序存储到靠近页的尾部的地方,这个地方就是所谓的Page Directory,也就是页目录(此时应该返回头看看页面各个部分的图)。页面目录中的这些地址偏移量被称为槽(英文名:Slot),所以这个页面目录就是由槽组成的。			

	注:最小记录的n_owned值为1,这就代表着以最小记录结尾的这个分组中只有1条记录,也就是最小记录本身。最大记录的n_owned值为5,这就代表着以最大记录结尾的这个分组中只有5条记录,包括最大记录本身还有我们自己插入的4条记录。
	当多条数据插入时分槽下图所示:

在这里插入图片描述

页面头部(Page Header)

用来标识一个数据页的存储记录的状态信息,比如本页中已经存储了多少条记录,第一条记录的地址是什么。

文件头部(File Header)

描述各种页通用的一些信息,比如当前页编号、它的上一页、它的下一页等。通过上一页和下一页的页号组成双向链表串联起来,而无需物理存储结构的连接(并不是所有类型的页都有上一个和下一个页的属性)。

File Trailer

为保证从内存中同步到磁盘的页的完整性,在页的首部和尾部都会存储页中数据的校验和和页面最后修改时对应的LSN值,如果首部和尾部的校验和和LSN值校验不成功的话,就说明同步过程出现了问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值