Innodb-ruby深入探索Innodb存储结构

达在之前已经分享过Innodb数据存储结构知识,但是都是基于理论原理知识理解,今天利用Innodb文件解析工具ruby进行探索Innodb真实的存储结构。

索引原理过程:【Mysql】 InnoDB引擎深入 - 数据页 | 聚集索引_innodb的聚集索引的数据插入_Survivor001的博客-CSDN博客

Innodb_ruby工具的安装过程也分享过,这里就不阐述了,具体的使用方法,可以查看官网git上面的介绍:Home · jeremycole/innodb_ruby Wiki · GitHub

1、场景描述

这里我创建了简单的一些表:project用来验证不同的理论原理知识:

project 表约2.3w笔数据:

主键索引:project_id

唯一索引:index(`tenantsid`, `code`)

简单说下innodb_space语法:

innodb_space从命令行使用的基础知识。有两种方法可以开始innodb_space

针对单个空间文件(ibdata 或 .ibd):

选项 参数 描述
-F <文件名> 加载表空间文件(系统或表)

针对将自动加载每个表文件的表空间文件的系统表空间:

选项 参数 描述
-s <文件名> 加载系统表空间文件(例如ibdata1)
-T <表名> 使用给定的表名称。
-I <索引名称> 使用给定的索引名称

注:使用innodb_space查看空间数据需要进入到mysql数据存储目录,我的目录:

/usr/local/mysql/data

2、通过Innodb_space查看系统表空间信息

innodb_space -s ibdata1 system-spaces;

Innodb-ruby深入探索Innodb存储结构_第1张图片

pages:总数据页数量,这里project表,一共使用到了704个 page页

indexes:总索引个数,project表我这里就是聚簇索引和唯一索引,分别就是PRIMARY主键,index(`tenantsid`, `code`)索引。

3、指定表查看索引空间信息 

innodb_space -s ibdata1 -T firestation/project space-indexes;

 id :索引ID,相同的ID表示是同一个索引

root:当前索引的根page页编号 ,可以看出来

fseg:类型,page的说明

used:索引使用到了多少page页,比如PRIMARY的叶子类型中为95,表明使用到了95个page页来存储数据(因为聚簇索引叶子节点存储了数据信息)

allocated:分配了多少page

fill_factor:page使用占比 :used / allocated

这里表示:

PRIMARY 索引树使用使用了1个root节点,该节点根page编号为3,leaf节点数据为95个page,实际分配了96个数据页。这里可以看出来,PRIMARY索引树是一个2层的多叉树结构:

Innodb-ruby深入探索Innodb存储结构_第2张图片

 

二级索引 index:1个root节点,page编号为7,leaf节点为42个page,实际分配了96个page,也是一个2层多叉树

Innodb-ruby深入探索Innodb存储结构_第3张图片

1、查看节点page空间信息

  已经知道了大致的索引结构了,现在可以详细查看一下指定page页信息

(1)查看主键PRIMARY root页面空间信息

innodb_space -s ibdata1 -T firestation/project -p 3 page-records

Innodb-ruby深入探索Innodb存储结构_第4张图片

Innodb-ruby深入探索Innodb存储结构_第5张图片

 这里可以看到在查看了page为3(PRIMARY索引的root页)的页信息后,一共出来95个page信息,对应了上述表述的95个leaf page,同时默认按照主键ID从小到大排序。

Innodb-ruby深入探索Innodb存储结构_第6张图片

之前理论知识也说过了,目录页会记录最小索引列编号,来作为目录检索,比如查询34000,那就是在33819~34232区间,指向page 6 号数据页里面,这个时候就会去6号page页检索。

所以理论上来说,page5 页中应该是存储了33649~33818之间的数据,下面来验证下

2、查看指定leaf-page空间信息

innodb_space -s ibdata1 -T firestation/project -p 5 page-records

这个打印出来内容比较多,因为所有数据都被展示了,这里我截取下前后id的信息:

这里可以看到首个数据是33649 , 结尾数据是33818,同时也发现了PRIMARY索引的leaf节点里面是有真实数据信息的。但是非叶子节点只有索引列信息,也就是主键ID。

(2)同样操作查看二级索引index空间信息

Innodb-ruby深入探索Innodb存储结构_第7张图片

可以看出来二级索引page数量明显少于聚簇索引page,因为二级索引是不存储其他业务数据字段信息的,所以每个page能存储更多的索引列信息。

同时可以发现联合索引,在non-leaf节点中存储了联合索引列,tenantsid 和 code两个字段信息,且优先索引列顺序,同时优先对tenantsid进行排序,然后对code进行排序。这也正对了前面说到的最左原则特性。

然后看看,leaf节点信息:

Innodb-ruby深入探索Innodb存储结构_第8张图片

可以看出来在二级索引的leaf节点中,是没有完整的数据信息的,处理索引列数据,还存储了主键id信息。这也验证了前面说到的,二级索引查询完成后会通过主键ID查询聚簇索引树。

Innodb-ruby深入探索Innodb存储结构_第9张图片

到这里基本上已经完全了解了Innodb索引数据存储原理了

有个问题?

为什么前面查看系统空间发现project总共使用了704个page,但是通过index空间查看使用到的page数量远小于这个数。

查看系统page使用和分布:

可以看出来,处理真实使用到索引数之外,还会有其他page存储数据,比如缓存、元空间信息等等,后续再详细分享。

你可能感兴趣的:(数据库,java,开发语言)