Mysql进阶索引篇02——InnoDB存储引擎的数据存储结构(一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 前面我们已经剖析了mysql中InnoDB与MyISAM索引的数据结构,了解了B+树的设计思想、原理,并且介绍了B+树与Hash结构、平衡二叉树、AVL树、B树等的区别和实际应用场景。页和页之间并不一定在物理上相连,只是在逻辑上使用双向链表关联。指针、记录究竟是如何存储的呢?其实这就需要联系我们之前提到的行格式了。数据查找在页目录中二分法快速定位到槽,上面的过程都与页的内部结构相关,本文将详细的阐述。

前言


前面我们已经剖析了mysql中InnoDBMyISAM索引的数据结构,了解了B+树的设计思想、原理,并且介绍了B+树与Hash结构平衡二叉树AVL树B树等的区别和实际应用场景。

页和页之间并不一定在物理上相连,只是在逻辑上使用双向链表关联。指针、记录究竟是如何存储的呢?其实这就需要联系我们之前提到的行格式了。数据查找在页目录中二分法快速定位到,上面的过程都与页的内部结构相关,本文将详细的阐述。

这篇文章将对InnoDB引擎的数据存储结构介绍,带大家熟悉数据库的页的存储结构与行格式,为之后的调优做准备。


1.数据库的存储结构:页

索引实际上是存储在文件上的,确切的说是存储在页结构中的。存储引擎负责数据的读、写操作,不同的存储引擎的数据格式可能不同。本文所介绍的数据库存储结构基于Mysql的InnoDB存储引擎。这也是我们实际工作中所使用的。

1.1 磁盘与内存交互的基本单位:页

InnoDB将数据划分为若干页,Mysql页的默认大小是16kb.可以使用下面的命令进行查看。

在sql server中,页的默认大小是8kb。Oracle中使用块*(Block)的概念来作为磁盘与内存的基本交互单位,块的大小可以是2kb,4kb,8kb,16kb,32kb和64kb。


这里我们强调,mysql中磁盘与内存交互的基本单位是页,这表示我们在磁盘与内存之间进行数据交互,最少是一页,并且每次交互都是整数页。即使我们数据存储只存储了一行,数据库I/O的操作单位也是一页。这样设计其实也是为了提高效率,毕竟I/O的时间消耗很大,不可能读、写一次数据就进行一次磁盘的I/O操作。


1.2 页上层结构

页的上层结构是,一个区会分配64个连续页,区的大小正好是1MB(16kb * 64)。

段由一个区或多个区组成。段是数据库的分配单位,比如我们创建一个表,就会创建一个表段,创建一个索引,就会创建一个索引段。总而言之,不同类型的数据库对象对应不同类型的段。


这里我们举一个例子,部队中能够与敌军战斗的基本单位是一个兵,就像数据库中内存与磁盘交互的基本单位是一个页。但是一场战争派出去的不可能只是一个兵,而是更大的单位,比如师。对应的,数据库内存分配的最小单位是一个块。


表空间(table space)是一个逻辑容器。表空间中存储的是一个或者多个段,每个段只能属于一个表空间。表空间又可以分为系统表空间,用户表空间,撤销表空间、临时表空间等。


2.页的内部结构

常见的页有数据页(保存b+树节点)、系统页Undo页事务数据页

页可以划分为如下的七个结构。

这七个结构的作用如下。

为了方便大家的理解,我们将他们归纳为三个部分,进行讲解。

2.1 文件头与文件尾

File Header与File Trailer主要是用于描述页的通用信息,用于页与页的交互或者数据的校验等。

  • FILE_PAGE_OFFSET:记录页编号,InnoDB可以通过页号唯一确定一个页。


FILE_PAGE_TYPE:代表当前页的类型,比如FILE_PAGE_UNDO_LOG(Undo日志页)、FILE_PAGE_TYPE_SYS(系统页)、FILE_PAGE_INDEX(索引页/数据页)。


FILE_PAGE_PREV与FILE_PAGE_NEXT上一页与下一页。


FILE_PAGE_SAPCE_OR_CHKSUM:校验和,对于一个较长的字符串,我们可以通过算法将其计算得到较短的字符串,即校验和,当我们需要比较两个长的字符串是否相等时,就比较他们校验和即可。同样我们也可以用校验和比较两个页是否相等。

文件尾页同样有校验和,它们是对应的。当我们对磁盘进行数据更新的刷盘执行I/O时,如果由于断电等原因导致数据传输中断,很可能一个页没有操作完。而页是数据库中磁盘与内存交互的基本单位,为了能够保证一致性,我们需要回滚或者将未写完的数据写完。我们如何判断是否写完呢?就是通过校验和。

具体的过程是:在内存向磁盘写入数据时,先更新File Header中的校验和,如果文件未正常写完,头尾校验和会不一致,如果未刷盘的数据有记录,就继续刷完,否则回滚。


FILE_PAGE_LSN:日志序列号,记录文件最后修改时对应的日志序列位置。尾部也有该字段,同样是为了校验页面的完整性。


2.2 记录部分:空闲空间、最大/小记录、用户记录

在最开始,我们会将已存储的数据按照行格式放到User Records,每插入一个数据,就会从Free Space申请一个记录大小的空间划分到User Records,直到Free Space都被转化为User Records空间,会申请一个新的页。User Records中的数据是按照单链表进行连接的。具体细节我们将在介绍行格式的用户头信息时介绍。


在介绍最小记录和最大记录之前,我们先思考一个问题,有必要对记录大小进行比较吗?当然是有必要的,因为我们的节点都是进行排序的。既然需要排序,就需要进行大小的比较了。那么,最大记录和最小记录的作用是什么呢?实际上,它就相当于记录的头、尾节点,这里我们先简单介绍,后面我们介绍完行格式,大家会对这部分理解更为深刻。在mysql中,最小记录与最大记录的格式非常简单,可以参考下图。

2.3 页目录与页头

page_decotory主要是为了方便数据进行二分查找。页目录是不是一开始就生成的呢?比如我们有1000条记录,是不是一开始就按照主键生成这1000条记录的页目录?这样做对于存储的占用显然是很高的。

实际上,mysql数据库做法如下。


将每页所有记录(包括最小记录与最大记录,不包含已删除记录)进行了分组,每个组取一个记录放入页目录中,占一个槽位(slot).最小记录单独为1组,最大记录所在组一般是有1-8条记录,其它组一般有4-8条记录。

每组的最后一条记录会存储一个n_owned属性,代表该组有几个记录。

页目录用于存储每组最后一个记录的地址偏移量。

下图表示了这个过程,其中每个记录的第一个字段就是n_owned.

现在我们已经知道页目录是如何生成的了,那么我们如何利用页目录进行数据的查找呢?实际上就是利用二分法对需要查找的数据与页目录中数据进行比较。比如一个数据确定比槽2的更大,比槽3的更小,那就可以去槽3所链接的分组4进行查找了。它会从槽2所链接的分组3最后一个记录指针链接到分组4的第一个元素,然后进行遍历查找。

接下来我们看看page header中记录了什么信息。这些信息大概了解下,主要是页的内部结构的一些信息。

其中PAGE_DIRECTION记录当前新插入记录是需要在上一条记录的前面还是后面插入。

2.4 从存储角度看普通索引和唯一索引有什么不同

我们到目前为止已经了解了页的内部结构和索引的数据结构。接下来我们深入思考一个问题。

普通索引和唯一索引有什么不同?

唯一索引指的是对索引字段加了唯一约束的索引,因此该字段不会重复。我们学习了页的存储结构以后知道,一般一个页默认大小是16kb,可以存放上千条记录,而且这些元素的存放是有序的,元素之间通过指针相连接。因此,普通索引一般只是在找到第一个元素后再多往后进行几次查找即可,其时间消耗并不大(真正消耗时间的是磁盘I/O)。


3.InnoDB行格式

3.1 行格式简介与操作sql

行格式就是记录的存储格式。

行格式一般有CompactDynamicCompressedRedundant几种。

可以使用如下的查询语句查询Mysql数据库的默认行格式。在mysql8与mysql5.7中,默认行格式都是dynamic

可以使用下列语句查询某个表实际使用的行格式。

使用如下语句可以在创建表时指定其行格式。

修改表的行格式。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
存储 算法 关系型数据库
InnoDB与MyISAM实现索引方式的区别
InnoDB和MyISAM均采用B+树索引,但在实现上有所不同。InnoDB的主键索引在叶子节点存储完整数据记录,辅助索引则存储主键值;而MyISAM的主键索引与数据文件分离,仅存数据地址,且主辅索引无区别,支持非唯一主索引。
15 1
|
13天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
120 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
28天前
|
存储 SQL 关系型数据库
MySQL存储引擎
本文介绍了数据库优化的多个方面,包括选择合适的存储引擎、字段定义原则、避免使用外键和触发器、大文件存储策略、表拆分及字段冗余处理等。强调了从业务层面进行优化的重要性,如通过活动设计减少外部接口调用,以及在高并发场景下的流量控制与预处理措施。文章还提供了具体的SQL优化技巧和表结构优化建议,旨在提高数据库性能和可维护性。
MySQL存储引擎
|
13天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
|
13天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
13天前
|
存储 缓存 关系型数据库
【赵渝强老师】MySQL的MyISAM存储引擎
在MySQL5.1版本之前,默认存储引擎为MyISAM。MyISAM管理非事务表,提供高速存储和检索,支持全文搜索。其特点包括不支持事务、表级锁定、读写互阻、仅缓存索引等。适用于读多、写少且对一致性要求不高的场景。示例代码展示了MyISAM存储引擎的基本操作。
|
13天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
19天前
|
存储 关系型数据库 MySQL
数据库引擎之InnoDB存储引擎
【10月更文挑战第29天】InnoDB存储引擎以其强大的事务处理能力、高效的索引结构、灵活的锁机制和良好的性能优化特性,成为了MySQL中最受欢迎的存储引擎之一。在实际应用中,根据具体的业务需求和性能要求,合理地使用和优化InnoDB存储引擎,可以有效地提高数据库系统的性能和可靠性。
35 5
|
13天前
|
存储 关系型数据库 MySQL
【赵渝强老师】MySQL的Memory存储引擎
MySQL 的存储引擎层负责数据的存储和提取,支持多种存储引擎,如 InnoDB、MyISAM 和 Memory。InnoDB 是最常用的存储引擎,从 MySQL 5.5.5 版本起成为默认引擎。Memory 存储引擎的数据仅存在于内存中,重启后数据会丢失。示例中创建了使用 Memory 引擎的 test3 表,并展示了数据在重启后消失的过程。
|
1月前
|
存储 SQL 缓存
MySQL存储引擎如何完成一条更新语句的执行!
MySQL存储引擎如何完成一条更新语句的执行!
MySQL存储引擎如何完成一条更新语句的执行!
下一篇
无影云桌面