MySQL InnoDB存储架构【2】——磁盘架构

前言

参考:MyQL官方文档
接上文 MySQL InnoDB存储架构【1】——内存架构
MySQL 版本 8.0.26

在这里插入图片描述
在 innoDB 存储引擎中,磁盘架构包含 表,索引,表空间,双写缓冲区,重做日志(redo log),撤销日志(undo logs)

1. 创建表时,表空间所在位置

从InnoDB的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)

  • file-per-table tablespace

    默认 innodb_file_per_table = 1, 创建表时,会在 file-per-table tablespace——@@datadir/{database}/下创建一个 {table_name}.idb 文件。

  • system tablespace

    如果set global innodb_file_per_table = 0,创建表时,就会在 system tablespace——@@datadir/ibdata1 中创建表空间,不会再创建数据和索引文件(对于MyISM 是分开的)

  • file-per-table tablespace 且目录在特定目录

    innodb_file_per_table = 1 或者建表时 使用tablespace file-per-table 子语句指定表空间, 并且使用 DATA DIRECTORY 指定目录。
    数据文件存储在指定目录

    # 查看几个相关路径, datadir 是数据库数据存储路径,
    SELECT @@datadir,@@innodb_data_home_dir,@@innodb_directories;
    # 数据目录,必须在innodb_directories 中
    # 如果没有需要在 mysql.conf 中 [mysqld] 做如下配置
    ## 以分号“;”分隔
    #innodb_directories="/opt/ext_data_dir/"
    
    CREATE TABLE t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/opt/ext_data_dir/';
    # CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE = innodb_file_per_table  DATA DIRECTORY = '/opt/ext_data_dir/';
    
    需要满足几个条件
    • 文件夹必须存在
    • 文件夹路径,必须在变量 innodb_directories 中
    • *ux 用户 mysql拥有 目录的权限
    • innodb_file_per_table = 1 或者建表时 使用 tablespace 子语句 指定表空间
  • general tablespace (通用表空间) // TODO

2. 表空间结构

参考 MySQL 8.0 Reference Manual 15.11.2 File Space Management

Extents, Segments 是逻辑上的定义。
page 是物理上概念,一个page代表一个连续的大小为 page size 的 物理空间

2.1 Page

每一个表空间都是由数据库 Page 组成的,对于一个数据库实例来说,Page 的大小都是一样的,默认是 16k。1
在这里插入图片描述

2.1 Extent

  • 对于 page size <= 16k , Extent 大小为 1M,即一个64个连续的 16k page, 128个 8k page, 256个 4k page
  • 对于 page size = 32k,Extent 大小为 2M,即一个 Extent 包含 64个 page
  • 对于 page size = 64k,Extent 大小为 4M,即一个 Extent 包含 64个 page

2.2 Segment

如果将 tablespace 当成目录,则 Segments 是它的文件

When a segment grows inside the tablespace, InnoDB allocates the first 32 pages to it one at a time. After that, InnoDB starts to allocate whole extents to the segment. InnoDB can add up to 4 extents at a time to a large segment to ensure good sequentiality of data.
当一个segment在表空间内增长时,InnoDB第一次分配前 32 Page 给它。之后,InnoDB分配 整个 Extent 到 Segment。 InnoDB 一次最多可以将 4 个 Extent 添加到一个大的 Segment 中,以确保数据的良好顺序性。

  • InnoDB 中的每个索引都分配了两个段。一种用于 B+ 树的非叶节点,另一种用于叶节点。
  • 使叶节点在磁盘上保持连续可以实现更好的顺序 I/O 操作,因为这些叶节点包含实际的表数据。
  • 对于聚簇索引来说,叶子节点保存了真实的记录
  • 叶子节点的数据结构是有序双向链表

2.4 文件结构

ibd 文件结构2
在这里插入图片描述

  1. FSP HEADER PAGE
    FSP HEADER PAGE 是表空间的root page,存储表空间关键元数据信息。由 page file header (文件信息)、fsp header(表空间元信息)、xdes entries(描述extent的xdes(extent descriptor)信息的链表) 三大部分构成
  2. IBUF BITMAP PAGE
    用于跟踪随后的每个page的change buffer, 使用4个bit来描述每个page的change buffer信息。3
  3. INODE PAGE
    表空间文件的第3个page的类型为FIL_PAGE_INODE,存储inode(index node),管理表空间的segment。每个inode对应一个segment。每个inode page默认存储FSP_SEG_INODES_PER_PAGE(85)个inode。每个索引使用2个segment,分别用于管理叶子节点和非叶子节点。
  4. 接下来的页,就是用来存储 索引 b+ 树的叶子节点和非叶子节点

我创建了一张最简单的表

create table t1(id int auto_increment primary key);

查看对应的表空间文件大小为 112k,也就是 7 页

  • FSP HEADER PAGE
  • IBUF BITMAP PAGE
  • INODE PAGE
  • 非叶子节点
  • 叶子节点
  • 预留page,新创建的表空间,且当前的文件小于1个Extent时,则只分配2个Page
    通过 innblock 查看数据
    在这里插入图片描述
root:/opt/project/innblock-master# ./innblock /var/lib/mysql/test/t2.ibd scan 16
Datafile Total Size:114688
===INDEX_ID:165
level0 total block is (1)
block_no:         4,level:   0|*|

参考文献


  1. InnoDB : Tablespace Space Management ↩︎

  2. MySQL · 引擎特性 · Innodb 表空间 ↩︎

  3. MySQL · 引擎特性 · InnoDB 文件系统之文件物理结构 ↩︎

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值