200_mysql_innodb_1_ Row_Format _page_聚簇_二级索引

举报
alexsully 发表于 2021/10/26 14:13:46 2021/10/26
【摘要】 innodb_Row_Format _page_聚簇_二级索引

前言;

1 Innodb 核心特性

MVCC : 多版本并发控制

聚簇索引 : 用来组织存储数据和优化查询

支持事务 : 数据最终一致提供保证

支持行级锁 : 并发控制, 保障 写 写之间的控制,保障一致性

外键 : 多表之间的数据一致一致性 多缓冲区支持

自适应Hash索引: AHI 复制中支持高级特性。

备份恢复: 支持热备。

自动故障恢复:CR Crash Recovery

双写机制 : DWB Double Write Buffer

2 查询版本

#客户端版本
 mysql -V 
#server 版本
select @@version; engine 版本: 
SELECT * FROM information_schema.plugins; 
SELECT @@innodb_version;

一 宏观结构

8.0 以前 InnoDB表: ibd数据和索引;  frm :存私有的数据字典信息;  ibdataN:系统的数据字典信息

8.0 之后只有ibd数据和索引+ 冗余的SDI私有数据字典信息 (对DDL有好处) SDI(每个表的表空间自行管理json格式的私有数据字 典信息,用来替换frm的。)

mysql.ibd ---> 整个系统的数据字典,不再放在ibdata1

二 微观物理结构

2.1 innodb记录存储结构

Innodb数据页16KB (show variables like "innodb_page_size";  #16384 16KB) 一次至少从磁盘读取16KB到内存,一次最少刷新16KB内容到磁盘

2.2 Innodb 行格式 Row_Format (Redundant Compact Dynamic Compressed)

show variables like "%Row_Format%"  # innodb_default_row_format dynamic
create table xxx() ROW_FORMAT=DYNAMIC

2.3 行格式的机构

1 记录额外的信息 (132字节)

  1. 变长字段长度信息列表形式 存储所有可变长度字段(varchar TEXT)的真实数据(NULL)占用的字节数 (逆序存放)
  2. NULL值列表: 二进制表示 1null0位非null (先判断表约束,然后根据实际情况 逆序存放 最终转成16进制)
  3. 记录头信息:5个字节(40个二进制位)组成 描述该记录的属性 

名称       

大小(bit)

    描述
预留位1        1               

没有使用

预留位2      1          

没有使用

delete_mask    1

标记该记录是否被删除,0 表示未删除,1表示删除,

min_rec_mask             1

 B+树的每层非叶子节点中的最小记录都会添加该标记 (只有目录项_非叶子节点存储此信息 1 表示,其它是0)

n_owned 4

  表示当前记录拥有的记录组数 带头大哥的组数为实际组数,小弟为0

heap_no 13

 表示当前记录在记录堆的位置信息 (user recordsheap一条条亲密无间排列的结构,每条记录在heap中的位置heap_no)

record_type           3

表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点(目录项)记录,2表示Infimum最小记录,3表示Supermum最大记录

next_record          16

表示下一条记录的相对位置

备注:

  1. 记录可以比大小,比的是主键
  2. 无论插入多少条记录,最小是Infimum (5字节记录头+8字节固定单词), 最大是Supremum
  3. Next record 当前记录到下一条记录的真实距离(理解为偏移量/指针 正数代表在下一条记录后面,负数代表前面, -111代表向前找111个字节)
  4. 无论对数据的增删改,innodb始终维护一个单项链表(链表各个节点由主键从小到大顺序链接)
  5. 页面前面的记录heap_no小,后面大,从2开始, 0-Infimum;1-Supremum最靠前

2 真实记录数据

  1. Row_id 6字节 ,行ID 唯一表示一条记录  非刚需,无主键情况下生成(无显示定义,可以选not null & UNIQUE的键)
  2. Trx_id 6 字节     事物ID 刚需
  3. Roll_pointer 7字节 回滚指针

溢出列

某列超出数据页范围 需在其他页面存储,其它页面即为溢出列(COMPACT&REDUNDANT格式 会存储真实记录的 768字节,再拿20字节存储其它位置的指针等信息)

溢出页临界点(MySQL中规定,一个也至少存两行记录 每行记录真实数据的属性信息27字节) 132+227+n< 16384 , n <8099 情况下不会有溢出列

DYNAMIC格式不会单独记录真实数据的前768个字节,仅拿20字节存储溢出页/列的位置

三 Innodb数据页结构

InnoDB存放不同数据页设计不同类型的页, 例如 index 页 Change buffer页,Inode页,undo页, 通用结构如下

3.1 Page Directory

Select * from xxx where id = xxx不会从infimum开始遍历,innodb会设计一种 类似书的目录结构,

  1. 将正常记录分成几组(包括infimum & supremum
  2. 每组最后一条也是最大记录是带头大哥,其余数据属于这位大哥(n_owned=0
  3. 带头大哥在页面中的偏移量(实际位置到第0个字节距离)取出,放在整改页的尾部(page directory) 这些偏移量成为槽 slot(每个slot2字节,相邻分布,越小越接近File Trailer
  4. Infimum所在组只能有1条记录,supremum所在组 1-8条, 剩下正常组 4-8

3.2  PageHeader 记录数据页中的状态信息 例如 Free space 偏移量,slot个数等

状态名称          占表空间 描述
PAGE_N_DIR_SLOTS    2字节     在Page Directory(页目录)中的Slot(槽)数
PAGE_HEAP_TOP  2字节  还未使用最小空间,在这之后就是Freespace
PAGE_N_HEAP    2字节 第一位标记是否为紧凑型记录, 其余15位表示堆中的记录数 (包括infumum supremum 以及已删除记录)
PAGE_FREE 2字节             已经删除的记录通过next_record组成一个单向链表, 其中所占用存储空间可以重用, page_free表示该链表头结点在页面中偏移量
PAGE_GARBAGE         2字节       已删除记录的字节数,即行记录结构中,delete flag为1的记录大小的总数。
PAGE_LAST_INSERT 2字节         最后插入记录的位置
PAGE_DIRECTION 2字节      最后插入的方向。可能的取值为PAGE_LEFT(0x01),PAGE_RIGHT(0x02),PAGE_SAME_REC(0x03),PAGE_SAME_PAGE(0x04),PAGE_NO_DIRECTION(0x05)。
PAGE_N_DIRECTION 2字节  一个方向连续插入记录的数量。
PAGE_N_RECS 2字节        该页中记录的数量(不包括已经删除记录和 infumum & supremum)
PAGE_MAX_TRX_ID 8字节 修改当前页的最大事务ID,注意该值仅在Secondary Index定义
PAGE_LEVEL 2字节  当前页在B+树种所处的层级 
PAGE_INDEX_ID 2字节 当前页属于哪个索引ID。
PAGE_BTR_SEG_LEAF 10字节 B+树的叶节点中,文件段的首指针位置。注意该值仅在B+树的Root页中定义。
PAGE_BTR_SEG_TOP 10字节 B+树的非叶节点中,文件段的首指针位置。注意该值仅在B+树的Root页中定义。

3.3 File header (文件头部信息 记录数据页记录的各种状态)

状态名称          占表空间 描述
FIL_PAGE_SPACE_OR_CHKSUM   4字节    

MySQL版本小于MySQL-4.0.14,该值代表该页所在表空间ID ,之后该值代表页的checksum值(一种新的checksum值)。

FIL_PAGE_OFFSET 4字节 

页号 (单独页号类似身份证)

FIL_PAGE_PREV 4字节

上一个页号  双向链表

FIL_PAGE_NEXT 4字节            

下一个页号 B+Tree特性决定了叶子节点必须是双向列表

FIL_PAGE_LSN      8字节      

页面最后被修改后修改时候的LSNLog Sequence Number

FIL_PAGE_TYPE 2字节         页的类型 请记住0x45BF,该值代表了存放的数据页
FIL_PAGE_FILE_FLUSH_LSN 8字节     

该值仅在系统表空间的第一页中定义,代表文件至少被更新到了该LSN

FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4字节 

该值代表页属于哪个表空间

数据页类型

类型名称

十六进制

描述

FIL_PAGE_TYPE_ALLOCATED

0x0000

最新分配,还没使用

FIL_PAGE_UNDO_LOG

0x0002

Undo 日志页

FIL_PAGE_INODE

0x0003

存储断的信息

FIL_PAGE_IBUF_FREE_LIST

0x0004

Change Buffer空闲列表

FIL_PAGE_IBUF_BITMAP

0x0005

Change Buffer 的一些属性

FIL_PAGE_TYPE_SYS

0x0006

存储一些系统数据

FIL_PAGE_TYPE_TRX_SYS

0x0007

事务系统数据

FIL_PAGE_TYPE_FSP_HDR

0x0008

表空间头部信息

FIL_PAGE_TYPE_XDES

0x0009

扩存储区的一些属性

FIL_PAGE_TYPE_BLOB

0x000A

溢出页

FIL_PAGE_INDEX

0x45BF

索引页,也就是数据页

3.4 File Trailer (文件尾部) 为了检测页是否已经完整地写入磁盘(如可能发生的写入过程中磁盘损坏、机器关机等)

 8个字节组成  分成2部分

前四个字节 代表也的校验和 File Header中的校验和对应

后四个字节 代表页面被最后修改时 对应的LSN的后四个字节FILE_PAGE_LSN后四个字节相同

Innodb存储引擎索引_B+树索引

表在插入过程中,分配的数据页不一定是连续的,由于主键索引从小到大排序,所以会有页的分裂产生,为了快速查找,制作目录(非叶子节点)

  1. 页的用户记录中最小的主键值 作为key
  2. 页号 用page_no 表示

B+ 树的根节点自创建日后不再移动

聚簇索引 主键的大小作为页和记录的排序规则, 叶子节点记录包含表中所有列

二级索引(辅助索引) 索引列(字段)的大小作为页和记录排序规则, 叶子节点存储的是索引列和主键

MyISAM 存储引擎的数据和索引分开存储, 索引均为二级索引,叶子节点存储的是列+行号

4.1 聚簇索引 使用主键的大小作为页和记录的排序规则

  • (包括叶子节点和内节点) 内的记录安装主键大小排序 –> 单向链表
  • 各存放用户记录的页节点也根据用户记录的主键大小排序 –> 双向链表
  • 存放目录项的页 层级不同,同层级中页也是根据目录项的主键大小排序 –>双向链表
  • B+树的叶子节点存储完整用户记录包括隐藏列

4.2 二级索引 单独一颗B+数 叶子节点存储列和主键ID以及页号

如果联合索引a1 a2 a3 会先按a1排序,a1相同a2排序,a2相同a3排序, 再对应主键(顺序打乱,随机IO)

创建索引

alter table t1 add index idx_k2(k2);

alter table t1 add index idx_k1_2(k1,k2);

alter table city add index idx_n(name(5));  # 前置索引

alter table city drop index idx_n

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。