InnoDB详解2

InnoDB详解2

1 行格式

规定每条记录是怎么存储的
MySQL 8默认行格式是Dynamic

InnoDB存储引擎设计了4种不同类型的`行格式`,分别是`Compact`、`Redundant`、`Dynamic`和`Compressed`行格式。
查看MySQL8的默认行格式:
mysql> SELECT @@innodb_default_row_format;
+-------------------------------------+
| @@innodb_default_row_format |
+-------------------------------------+
| dynamic                                   |
+-------------------------------------+
1 row in set (0.00 sec)
也可以使用如下语法查看具体表使用的行格式:
SHOW TABLE STATUS like '表名'\G

1 Compact行格式详解

image-20221223101452542

1 变长字段长度列表(两个字节)

在每条记录开始存入变长字段列表。没有变长字段就没有该项。小端存储。

如VARCHAR(M)、VARBINARY(M)、TEXT类型,BLOB类型,这些数据类型修饰列称为变长字段,变长字段中存储多少字节的数据不是固定的,所以我们在存储真实数据的时候需要顺便把这些数据占用的字节数也存起来。在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表

image-20221223101918763

2 NULL值列表(1个字节)

为什么定义NULL值列表?

之所以要存储NULL是因为数据都是需要对齐的,如果没有标注出来NULL值的位置,就有可能在查询数据的时候出现混乱。如果使用一个特定的符号放到相应的数据位表示空置的话,虽然能达到效果,但是这样很浪费空间,所以直接就在行数据得头部开辟出一块空间专门用来记录该行数据哪些是非空数据,哪些是空数据

用于标识哪些是null值,1位null ,0不为null。允许为null的字段才会有该记录。

明确表明该字段不为null值时,不会记录

如 一条记录 有 ABC 三个字段 A是主键 BC可以为null 该记录 A = 1 ,B= null ,C = 2, NULL值列表存的是 0 1 ,0表示C不是null,1表示 B是null。A是主键不能为null 所以不用存。

3 记录头信息 (重点)

image-20221223103105152

image-20221223103153625

image-20221223104814392

delete_mask:当删除数据时,只需要将delete_mask标识位1。

占用1个二进制位。

  • 值为0:代表记录并没有被删除

  • 值为1:代表记录被删除掉了

被删除的记录为什么还在页中存储呢?

这些被删除的记录之所以不立即从磁盘上移除,是因为移除它们之后其他的记录在磁盘上需要重新排列,导致性能消耗。所以只是打一个删除标记而已,所有被删除掉的记录都会组成一个所谓的垃圾链表,在这个链表中的记录占用的空间称之为可重用空间,之后如果有新记录插入到表中的话,可能把这些被删除的记录占用的存储空间覆盖掉。

min_rec_mask:B+树的每层非叶子节点中的最小记录都会添加该标记,min_rec_mask值为1。

record_type:

这个属性表示当前记录的类型,一共有4种类型的记录:

0:表示普通记录

1:表示B+树非叶节点记录

2:表示最小记录

3:表示最大记录

heap_no:每条记录在此页中的位置,(Infimum )最小记录和(Supremum)最大记录的heap_no值分别是0和1,其他记录往后顺延。

**n_owned :**页目录中每个组中最后一条记录的头信息中会存储该组一共有多少条记录,作为 n_owned 字段。分组也叫slot槽,槽位记录的是最大记录的地址偏移,最后一条记录记录该组中有几条记录。

**next_record:**从当前记录的真实数据到下一条记录的真实数据的地址偏移量

image-20221223110220833

删除操作

image-20221223110429030

删除第二条记录时,先根据页目录二分查找到 槽位,然后进行遍历,遍历到第二条记录,delete_mask改为1,next_record改为0,第一条记录链接到第三条记录。该分组中 最后一条记录的n_owned由5变为4 (最小记录自成一组)

当数据页中存在多条被删除掉的记录时,这些记录的next_record属性将会把这些被删除掉的记录组成一个垃圾链表,以备之后重用这部分存储空间。

所以,不论我们怎么对页中的记录做增删改操作,InnoDB始终会维护一条记录的单链表,链表中的各个节点是按照主键值由小到大的顺序连接起来的

添加操作

image-20221223111331148

2 Dynamic行格式

MySQL对一条记录占用的最大存储空间是有限制的,除BLOB或者TEXT类型的列之外, 其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节。

这个65535个字节除了列本身的数据之外,还包括一些其他的数据,以Compact行格式为例,比如说我们为了存储一个VARCHAR(M)类型的列,除了真实数据占有空间以外,还需要记录的额外信息。

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

CREATE TABLE varchar_size_demo(

c VARCHAR(65532)

) CHARSET=ascii ROW_FORMAT=Compact;

如果有not null属性,那么就不需要NULL值标识,也就可以多存储一个字节,即65533个字节

我们可以知道一个页的大小一般是16KB,也就是16384字节,而一个VARCHAR(M)类型的列就最多可以存储65533个字节,这样就可能出现一个页存放不了一条记录,这种现象称为行溢出

CompactReduntant行格式中,存不下的数据就存一部分数据和其他数据的页地址,其他数据放到其他页中。

CompressedDynamic两种记录格式对于存放在BLOB中的数据采用了完全的行溢出的方式。如图,在数据页中只存放20个字节的指针(溢出页的地址),实际的数据都存放在Off Page(溢出页)中。

image-20221223112438374

所以 Dynamic 与Compact的区别就是对行溢出处理不一样,dynamic只存溢出页的地址,compact还存了一部分数据。

2 页的上层结构

image-20221223112830884

​ 页中由一条条行记录构成,我们知道页之间是由双向链表连接的。如果连续的两个页之间真实地址相隔很远。磁盘寻道扫描速度很慢,

如果一个查询需要用到100个数据页,最坏情况下需要磁盘扫描100次。为了减少IO次数,所以有了区的概念

image-20221223113332702

在数据扫描时,要先获取非叶子节点,如果将叶子节点与非叶子节点存放到一个区中,我们要的是叶子节点的数据,此时这个区中叶子节点数据很少,大部分是非叶子节点,获取真实数据时,还要扫描其他区,为了避免这种情况,引入了段的概念

image-20221223113902661

也就是将叶子节点数据放到一个区中,非叶子节点放到一个区中,专门存叶子节点或者专门存非叶子节点的区就叫做段,创建一个索引时就会分配2个段。

表空间是一个逻辑概念。

碎片区

此时创建一个表,插入一条数据。若按照 区,段的划分,此时一条数据就要构建一个聚簇索引 要分配两个区。需要 16k * 64 * 2 = 2M的空间。(一个页16K,一个区有64页,索引有叶子节点与非叶子节点 要两个段)很浪费空间。

就引入了碎片区的概念

碎片区属于表空间,该碎片去可以存段A的数据,也可以存段B的数据,就是什么都能存。

所以新建表的空间分配策略是,先找个碎片区分配空间,当一个表占用32个碎片区页面后,就会申请完整的区来存储数据。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
InnoDBMySQL 关系型数据库管理系统的一种存储引擎。它使用了一种称为"多版本并发控制"(MVCC)的技术来提供高性能和高并发性能。下面是 InnoDB 存储引擎的架构详解: 1. 缓冲池(Buffer Pool):InnoDB 使用了一个内存缓冲池来存储数据和索引。这个缓冲池是 InnoDB 存储引擎的关键组件,它用于减少磁盘 I/O 操作,提高性能。当数据被修改时,首先会被写入缓冲池中,然后再由后台线程将其刷新到磁盘。 2. 重做日志(Redo Log):InnoDB 使用了重做日志来保证事务的持久性。重做日志记录了对数据库进行的所有修改操作,包括插入、更新和删除操作。当系统崩溃或发生故障时,可以通过重做日志来恢复数据库的一致性。 3. 数据文件:InnoDB 将数据和索引存储在数据文件中。每个表都有一个对应的数据文件,其中包含了表的数据和索引信息。InnoDB 支持自动扩展和自动收缩数据文件的功能。 4. 页(Page):InnoDB 将数据和索引分成固定大小的页来管理。默认情况下,一个页的大小为 16KB。每个页都有一个唯一的标识符,称为页号。InnoDB 使用这些页来存储数据和索引。 5. 事务管理:InnoDB 支持事务的 ACID 特性(原子性、一致性、隔离性和持久性)。它使用了多版本并发控制(MVCC)来实现高并发性能和数据一致性。 6. 锁机制:InnoDB 使用了行级锁来控制并发访问。这意味着多个事务可以同时读取同一张表的不同行,而不会相互阻塞。只有当多个事务尝试修改同一行时,才会发生冲突。 总的来说,InnoDB 存储引擎的架构设计旨在提供高性能、高并发性能和数据一致性。它通过缓冲池、重做日志、数据文件、页、事务管理和锁机制等组件来实现这些目标。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值