Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > mysql表空间结构

MySQL表空间结构详解表空间到段页操作

作者:JhonKI

在MySQL架构和存储引擎专题中介绍了使用不同存储引擎创建表时生成的表空间数据文件,在本章节主要介绍使用InnoDB存储引擎创建表时生成的表空间数据文件,对mysql表空间结构及表空间到段页相关知识感兴趣的朋友一起看看吧

在MySQL架构和存储引擎专题中介绍了使用不同存储引擎创建表时生成的表空间数据文件,在本章节主要介绍使用InnoDB存储引擎创建表时生成的表空间数据文件

🏳️‍🌈一、什么是表空间结构

创建表时生成的数据文件在哪里?

表空间文件是用来存储表中数据的文件,表空间文件的大小由存储的数据多少决定,不同的表空间文件存储数据的种类也有所不同

在MySQL中表空间分为五类,包括: 系统表空间独立表空间通用表空间临时表空间撤销表空间,这些在上面的InnoDB架构图中都有体现。

1.1 表空间与表空间文件的关系是什么?

表空间可以理解为MySOL为了管理数据而设计的一种数据结构,主要描述的对结构的定义,表空间文件是对定义的具体实现,以文件的形式存在于磁盘上

系统表空间、独立表空间、通用表空间、临时表空间和撤销表空间的作用?
后面我们会详细介绍每种类型的表空间的作用。

🏳️‍🌈二、用户数据在表空间中是怎么存储的?

🏳️‍🌈三、为什么要使用页这个数据管理单元?

MySQL根据自身的应用场景使用页做为数据管理单元,最主要的目的就是减少磁盘I0,提高性能。

3.1 什么是局部性原理?

局部性原理是指程序在执行时呈现出局部性规律,在一段时间内,整个程序的执行仅限于程序中的某一部分。相应地,执行所访问的存储空间也局限于某个内存区域,局部性通常有两种形式:时间局部性和空间局部性。

🏳️‍🌈四、数据页有哪些基本特性是必须要掌握的? - 页

mysql> SHOW VARIABLES LIKE 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 | # 16KB
+------------------+-------+
1 row in set, 1 warning (0.04 sec)

在不同的使用场景中,页的结构也有所不同,在MVSOL中有多种不同类型的页,但不论哪种类型的页都会包含页头(File Header)和页尾(File Trailer),在这页头和页尾之间的页主体信息根据不同的类型有不同的结构,最常用的就是用来存储数据和索引的"索引页",也叫做"数据页",页的主体信息使用数据"行"进行填充,行的结构我们在下面的章节中进行详细介绍,页的基本结构如下图所示:

🏳️‍🌈五、查询的数据超过一页的大小,怎么提高查询效率? - 区

要解答这个问题,我们先要弄明白前置的几个小问题,首先通过前面的内容,我们了解到磁盘中每个页内部的地址都是连续的,那么我们可以继续提问:

1. 不同的页在磁盘中是不是连续的?
2. 如果页不连续对访问效率是否有影响?
3. InnoDB如何保证页在磁盘中的连续性?

解决以上三个小问题之后当前的问题自然也就解决了,我们接着往下看。

5.1 不同的页在磁盘中是不是连续的呢?

5.2 为什么不连续的地址会降低查询的效率?

扇区是磁盘中存储数据的最小单位,固定为 512B

经过以上的分析,当查询的数据大于一页时不加任何控制会产生磁盘随机访问 ,这个是影响查询效率的主要因素,那么现在怎么提高查询效率的问题就变成了,页在磁盘中是否连续的问题,我们换个问法。

5.3 InnoDB如何保证页在磁盘中的连续性?

提示: 我们学习的主要是解决问题的思路,大家要搞懂为什么要有区以及区解决了什么问题,至于区的固定大小不用刻意去记,现阶段是1MB,以后的版本会不会改变也说不好。同时,如果频繁的读取某个区中的页,可以把整个区都读取出来放入内存中,减少后续查询对磁盘的访问次数,进一步提升效率,如图所示

通过对问题的分析,我们了解到 InnoDB 中用来组织页的数据结构–区,并且每个区固定大小为1MB ,可以包含64个连续的页,查询的数据超过一页大小时,可能会有以下几种情况:

那么又有一个问题来了,新创建表时没有数据,或者说有的表只有很少的数据,1MB的空间用不完,那不是就存在空间浪费的问题吗?

5.4 当表中的数据很少时如何避免空间浪费?

通过 零散页 和 碎片区 避免空间浪费的问题

mysql> select * FROM information_schema.INNODB_TABLESPACES WHERE name = 'test_db/student'\G
*************************** 1. row ***************************
          SPACE: 9
           NAME: test_db/student
           FLAG: 16417
     ROW_FORMAT: Dynamic
      PAGE_SIZE: 16384					# 页大小
  ZIP_PAGE_SIZE: 0
     SPACE_TYPE: Single
  FS_BLOCK_SIZE: 4096
      FILE_SIZE: 114688					# 数据文件初始大小
 ALLOCATED_SIZE: 114688
AUTOEXTEND_SIZE: 0
 SERVER_VERSION: 8.0.42
  SPACE_VERSION: 1
     ENCRYPTION: N
          STATE: normal
1 row in set (0.00 sec)
# 根据数据文件大小和每页大小计算出页数
# 114688 / 16348 = 7 个数据页

这些零散页会放在表空间中一个叫碎片区的区域,随着数据量的增加,会申请新的页来存储数据,当碎片区达到 32个页 的时候,后续每次都会申请 一个完整的区 来存储更多的数据

🏳️‍🌈六、如果访问的数据跨区了怎么办? - 区组

MySQL使用 Extent(区) 这个结构来管理页,规定每个区固定大小为 1MB ,可以存放 64 个页

不同的区在磁盘上大概率是不连续的,那么这个问题其实是InnoDB如何高效的的管理区?

第一个区组中的首个区的前四页比特殊,也就是初始页中的前4页,分别是

其他区组中首个区的结构都一样,前两个页分别是:

使用 区组 结构有效的管理区,每个区组固定管理256个区即256MB,区组条目信息 中会记录每个区的偏移并用双向链表连接。

🏳️‍🌈七、以上这些数据结构还有优化的空间吗? - 段

当然是有的,InnoDB使用""这个逻辑结构区分不同功能的区和在碎片区中的页,并按功能分为"叶子节点段"和"非叶子节点段",做为B+树索引中的叶子、非叶子节点,从而进一步提升查询效怒。

以上讲到的区、区组还有页这种都是物理结构

在物理结构的基础上,定义了一个逻辑上的概念,也就是"";

"段"并不对应表空间中的连续的物理区域,可以看做是"区"和"页"的一个附加标注信息,段的主要作用是区分不同功能的区和在碎片区中的页,主要分为"叶子节点段"和"非叶子节点段"等,这两个段和我们常说的B+树索引中的叶子、非叶子节点对应,

可以简单的理解为

从逻辑上讲,最终由"叶子节点段"和"非叶子节点段"等段构成了表空间 .ibd 文件,如下图所示:

🏳️‍🌈八、延伸问题

8.1 上面讲的所有操作是在哪里进行的?

8.2 查询数据时 MySQL 会一次把表空间中的数据全部加载到内存吗?

8.3 每查询一条数据都要进行一次磁盘I/0吗?

👥总结

本篇博文对 【MySQL】表空间结构 - 从何为表空间到段页详解 做了一个较为详细的介绍,不知道对你有没有帮助呢

到此这篇关于MySQL表空间结构详解表空间到段页操作的文章就介绍到这了,更多相关mysql表空间结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文