MySQL索引页

compact行格式

额外消息记录

image_1c9g4t114n0j1gkro2r1h8h1d1t16.png

1.变长字段长度列表

列用的字符集是ascii,所以每个字符占一个字节

列名存储内容内容长度(十进制表示)内容长度(十六进制表示)
c1'aaaa'40x04
c2'bbb'30x03
c4'd'10x01
  • 逆向存放 01 03 04
  • 存储变长数据字节或不定字符集数据字节(utf8的字节为1-3是不确定的)

假设某个字符集中表示一个字符最多需要使用的字节数为W对于变长类型VARCHAR(M)来说,这种类型表示能存储最多M个字符(注意是字符不是字节),所以这个类型能表示的字符串最多占用的字节数就是M×W

if M×W <= 255:使用1个字节来表示真正字符串占用的字节数;

else M×W > 255:

​ L为实际数据占用的字节

  • 如果L <= 127,则用1个字节来表示真正字符串占用的字节数。
  • 如果L > 127,则用2个字节来表示真正字符串占用的字节数。
2.NULL值列表
  • 逆序
  • 二进制位的值为1时,代表该列的值为NULL;二进制位的值为0时,代表该列的值不为NULL
  • 一个字节起步,若只有3个值则补零

image_1c9g8g27b1bdlu7t187emsc46s61.png-19.4kB

3.记录头信息
名称大小(单位:bit)描述
预留位11没有使用
预留位21没有使用
delete_mask1标记该记录是否被删除
min_rec_mask1B+树的每层非叶子节点中的最小记录都会添加该标记(非数据页)
n_owned4表示当前记录(组)拥有的记录数
heap_no13表示当前记录在记录堆的位置信息
record_type3表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录
next_record16表示下一条记录的相对位置

记录的真实数据

MySQL会为每个记录默认的添加一些列(也称为隐藏列),具体的列如下:

列名是否必须占用空间描述
row_id6字节行ID,唯一标识一条记录(如果设置了主键或唯一数据列则该列不会生成)
transaction_id6字节事务ID
roll_pointer7字节回滚指针

image_1c9h256f9nke14311adhtu61ie2dn.png-92kB

Redundant行格式

image_1c9h8tnav166c187m1nhap61153qgn.png-91.6kB

第一列(`row_id`)的长度就是 0x06个字节,也就是6个字节。

第二列(`transaction_id`)的长度就是 (0x0C - 0x06)个字节,也就是6个字节。

第三列(`roll_pointer`)的长度就是 (0x13 - 0x0C)个字节,也就是7个字节。

第四列(`c1`)的长度就是 (0x17 - 0x13)个字节,也就是4个字节。

第五列(`c2`)的长度就是 (0x1A - 0x17)个字节,也就是3个字节。

第六列(`c3`)的长度就是 (0x24 - 0x1A)个字节,也就是10个字节。

第七列(`c4`)的长度就是 (0x25 - 0x24)个字节,也就是1个字节。

行溢出数据

我们为了存储一个VARCHAR(M)类型的列,其实需要占用3部分存储空间:

  • 真实数据
  • 真实数据占用字节的长度
  • NULL值标识,如果该列有NOT NULL属性则可以没有这部分存储空间

如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据,因为真实数据的长度可能占用2个字节,NULL值标识需要占用1个字节

如果VARCHAR(M)类型的列使用的不是ascii字符集,那M的最大取值取决于该字符集表示一个字符最多需要的字节数。在列的值允许为NULL的情况下,gbk字符集表示一个字符最多需要2个字节,那在该字符集下,M的最大取值就是32766(也就是:65532/2),也就是说最多能存储32766个字符;utf8字符集表示一个字符最多需要3个字节,那在该字符集下,M的最大取值就是21844,就是说最多能存储21844(也就是:65532/3)个字符。

compact行格式

image_1conbskr7apj19ns1d194vs1buo1t.png-35.8kB

Dynamic和Compressed(压缩算法对页面压缩)行格式

image_1conbtnmr1sg1hao1nf41pi1eb72a.png-29.9kB

数据页

页的大小都为16kb

img

名称中文名占用空间大小简单描述
File Header文件头部38字节页的一些通用信息(页名,上下页,类型…)
Page Header页面头部56字节数据页专有的一些信息(槽数,数据行数…)
Infimum + Supremum最小记录和最大记录26字节两个虚拟的行记录
User Records用户记录不确定实际存储的行记录内容
Free Space空闲空间不确定页中尚未使用的空间
Page Directory页面目录不确定页中的某些记录的相对位置
File Trailer文件尾部8字节校验页是否完整

插入数据过程

记录头信息

image_1cot1r96210ph1jng1td41ouj85c13.png-120.5kB

名称大小(单位:bit)描述
预留位11没有使用
预留位21没有使用
delete_mask1标记该记录是否被删除
min_rec_mask1B+树的每层非叶子节点中的最小记录都会添加该标记
n_owned4表示当前记录拥有的记录数
heap_no13表示当前记录在记录堆的位置信息(下标)
record_type3表示当前记录的类型,0表示普通记录,1表示B+树非叶节点记录,2表示最小记录,3表示最大记录
next_record16表示下一条记录的相对位置(指针)

image-20240202222006653

  1. 指针指向中间
  2. 删除的行不会立刻清除,但插入相同数据时会恢复

页目录(page directory)

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

image_1d6g64af2sgj1816ktl1q22dehp.png-189.1kB

  • 最小记录组只能有一行数据
  • 最大记录组数据行数1-8行
  • 其余4-8行
查询是通过二分查找来查询

File Header(文件头部)

名称占用空间大小描述
FIL_PAGE_SPACE_OR_CHKSUM4字节页的校验和(checksum值)(类似与hash转化,将长字符转化为短字符进行比较)
FIL_PAGE_OFFSET4字节页号
FIL_PAGE_PREV4字节上一个页的页号
FIL_PAGE_NEXT4字节下一个页的页号(页与页之间是双向列表)
FIL_PAGE_LSN8字节页面被最后修改时对应的日志序列位置(英文名是:Log Sequence Number)
FIL_PAGE_TYPE2字节该页的类型(MySQL有许多种页)
FIL_PAGE_FILE_FLUSH_LSN8字节仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID4字节页属于哪个表空间

Page Header(页面头部)

名称占用空间大小描述
PAGE_N_DIR_SLOTS2字节在页目录中的槽数量
PAGE_HEAP_TOP2字节还未使用的空间最小地址,也就是说从该地址之后就是Free Space
PAGE_N_HEAP2字节本页中的记录的数量(包括最小和最大记录以及标记为删除的记录)
PAGE_FREE2字节第一个已经标记为删除的记录地址(各个已删除的记录通过next_record也会组成一个单链表,这个单链表中的记录可以被重新利用)
PAGE_GARBAGE2字节已删除记录占用的字节数
PAGE_LAST_INSERT2字节最后插入记录的位置
PAGE_DIRECTION2字节最后记录插入的方向
PAGE_N_DIRECTION2字节一个方向连续插入的记录数量
PAGE_N_RECS2字节该页中记录的数量(不包括最小和最大记录以及被标记为删除的记录)
PAGE_MAX_TRX_ID8字节修改当前页的最大事务ID,该值仅在二级索引中定义
PAGE_LEVEL2字节当前页在B+树中所处的层级
PAGE_INDEX_ID8字节索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAF10字节B+树叶子段的头部信息,仅在B+树的Root页定义
PAGE_BTR_SEG_TOP10字节B+树非叶子段的头部信息,仅在B+树的Root页定义

You can’t connect the dots looking forward; you can only connect them looking backwards. So you have to trust that the dots will somehow connect in your future. You have to trust in something - your gut, destiny, life, karma, whatever. This approach has never let me down, and it has made all the difference in my life

File Trailer(文件尾部)

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

    这个部分是和File Header中的校验和相对应的。每当一个页面在内存中修改了,在同步之前就要把它的校验和算出来,因为File Header在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的。如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer中的校验和代表着原先的页,二者不同则意味着同步中间出了错。

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

er在页面的前边,所以校验和会被首先同步到磁盘,当完全写完时,校验和也会被写到页的尾部,如果完全同步成功,则页的首部和尾部的校验和应该是一致的。如果写了一半儿断电了,那么在File Header中的校验和就代表着已经修改过的页,而在File Trailer`中的校验和代表着原先的页,二者不同则意味着同步中间出了错。

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

    这个部分也是为了校验页的完整性的,只不过我们目前还没说LSN是个什么意思,所以大家可以先不用管这个属性。

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值