当前位置: 首页 > news >正文

InnoDB文件物理结构解析2 - FIL_PAGE_INDEX

1. 关于索引组织表

InnoDB使用的是索引组织表(IOT)的方式存储表记录,索引组织表以主键构建一个B-tree的数据结构来存储行记录,行记录存储在树的叶节点内。这与Oracle数据库是不同的,Oracle数据库默认创建的表是堆组织表(HOT),HOT记录按堆数据结构进行存储。在InnoDB中,我们将存储行记录的B-tree索引称为Clustered Index, 而表的相关普通B-tree索引(非主键索引)称为Secondary Index。

The data in each table is divided into pages. The pages that make up each table are arranged in a tree data structure called a B-tree index. Table data and secondary indexes both use this type of structure. The B-tree index that represents an entire table is known as the clustered index, which is organized according to the primary key columns. The nodes of a clustered index data structure contain the values of all columns in the row. The nodes of a secondary index structure contain the values of index columns and primary key columns.

存储Clustered Index的节点(页)与Secondary Index的的节点的内容是不一样的,树结构,包含页节点(Leaf)和非叶节点(Non-Leaf),前文提到,InnoDB中表的记录和相关索引都使用FIL_PAGE_INDEX Page存储,要解析一个FIL_PAGE_INDEX页的第一步就是要确定这个页存储的是什么数据。

1. FIL_PAGE_INDEX Page的结构

前文提到,表和其相关索引的数据是存储在FIL_PAGE_INDEX页的,那么我们首先看看FIL_PAGE_INDEX的页结构:

    0+--------------------------+| FIL Header (38)          |38+--------------------------+| INDEX Header (36)        |74+--------------------------+| FSEG Header (20)         |94+--------------------------+| System Records (26)      |120+--------------------------+| User Records             | // Records are un-ordered physically, 物理无序(不按主键顺序)存放, 类似于堆表|                          | // 但会由一个单向链表(singly-linked)将用户记录按主键有序串起来。+--------Heap Top----------+ // Heap Top是Page空间使用的高水位(HWM)| Free Space               |+--------------------------+| Page Directory           | // The page directory grows downwards from the FIL trailer in ascending order by key. //空间占用从后往前增长|                          | // The number of entries is stored in the INDEX header. 数量记录在INDEX Header->PAGE_N_DIR_SLOTS中。
16376+--------------------------+| FIL Trailer (8)          |
16384+--------------------------+
* 前面的数字是在Page内的偏移(bytes)

解析的第一步需要解析FIL_PAGE_INDEX的INDEX_Header结构:

38 +----------------------+ | PAGE_N_DIR_SLOTS (2) |
40 +----------------------+| PAGE_HEAP_TOP (2)    |
42 +----------------------+| PAGE_N_HEAP (2)      |
46 +----------------------+| PAGE_FREE (2)        |
48 +----------------------+ | PAGE_GARBAGE (2)     |
50 +----------------------+| PAGE_LAST_INSERT (2) |
52 +----------------------+| PAGE_DIRECTION (2)   |
52 +----------------------+| PAGE_N_DIRECTION (2) |
54 +----------------------+| PAGE_N_RECS (2)      |
56 +----------------------+| PAGE_MAX_TRX_ID (2)  |
64 +----------------------+| PAGE_LEVEL (2)       |
66 +----------------------+ | PAGE_INDEX_ID (2)    |
73 +----------------------+ * 前面的数字是在Page内的偏移(bytes)

通过解析INDEX_Header,我们就可以知道FIL_PAGE_INDEX存储的是哪个索引,记录类型,page level, …:

public class IdxPage1 {public static void main(String[] args) throws IOException, Exception {String fileName = "D:\\Data\\mysql\\8.0.18\\data\\sakila\\film.ibd";try (IbdFileParser parser = new IbdFileParser(fileName)) {List<Long> pageNums = parser.getPageTypeMap().get(FilHeader.FIL_PAGE_INDEX);StringBuilder buff = new StringBuilder();buff.append(" PAGE       PAGE_TYPE LEVEL INDEX_ID   PAGE_PREV   PAGE_NEXT\n").append("----- --------------- ----- -------- ----------- -----------\n");for (long pageNum : pageNums) {IndexPage indexPage = (IndexPage) parser.getPage(pageNum);FilHeader filHeader = indexPage.getFilHeader();IndexHeader indexHeader = indexPage.getIndexHeader();buff.append(String.format("%5d ", pageNum)).append(String.format("%15s ", filHeader.getPageTypeName())).append(String.format("%5d ", indexHeader.getPageLevel())).append(String.format("%8d ", indexHeader.getIndexId())).append(String.format("%11d ", filHeader.getPreviousPage())).append(String.format("%11d ", filHeader.getNextPage())).append("\n");}System.out.println(buff);}}
}
 程序输入:PAGE       PAGE_TYPE LEVEL INDEX_ID   PAGE_PREV   PAGE_NEXT
----- --------------- ----- -------- ----------- -----------4  FIL_PAGE_INDEX     1      596  4294967295  4294967295 5  FIL_PAGE_INDEX     1      597  4294967295  4294967295 6  FIL_PAGE_INDEX     0      598  4294967295  4294967295 7  FIL_PAGE_INDEX     0      599  4294967295  4294967295 8  FIL_PAGE_INDEX     0      596  4294967295           9 9  FIL_PAGE_INDEX     0      596           8          10 10  FIL_PAGE_INDEX     0      596           9          11 11  FIL_PAGE_INDEX     0      596          10          12 12  FIL_PAGE_INDEX     0      596          11          13 13  FIL_PAGE_INDEX     0      596          12          14 14  FIL_PAGE_INDEX     0      596          13          15 15  FIL_PAGE_INDEX     0      596          14          18 16  FIL_PAGE_INDEX     0      597  4294967295          17 17  FIL_PAGE_INDEX     0      597          16  4294967295 18  FIL_PAGE_INDEX     0      596          15          19 19  FIL_PAGE_INDEX     0      596          18          20 20  FIL_PAGE_INDEX     0      596          19  4294967295 

首先我们观察INDEX_ID,这是索引在InnoDB中的唯一编号,通过输出我们可以看到sakila.film表有4个索引,编号分别为: 596, 597, 598和599,INDEX_ID对应的页存储的就是该索引的数据。我们可以在MySQL中查到对应信息:

selectidx.space space_id,idx.page_no,index_id,idx.name index_name,tab.name table_name
from innodb_indexes idx, innodb_tables tab
whereidx.table_id = tab.table_idand index_id in(596, 597, 598, 599);--语句输出: 
space_id|page_no|index_id|index_name                 |table_name |
--------+-------+--------+---------------------------+-----------+387|      4|     596|PRIMARY                    |sakila/film|387|      5|     597|idx_title                  |sakila/film|387|      6|     598|idx_fk_language_id         |sakila/film|387|      7|     599|idx_fk_original_language_id|sakila/film|

这与我们解析的结果是一致的。结合PAGE_LEVEL和PAGE_PREV/PAGE_NEXT信息可以得到整棵B-Tree的基本层次结构, 以主键(PRIMARY, 596)为例,我们可以看到596号索引最大的page_level为1,位于page(4), 最大的level代表着树的根节点(root), page4的page_next和page_prev都为0xffffffff(4294967295),可以理解为指向自己或者终结。page(8)的page_prev为0xffffffff,level=0,代表叶节点,是叶节点的最左边节点。page(20)的page_nex为0xffffff, level=0, 说明是叶子节点最右边的节点。所以根据解析输出,我们可以描绘树的基本结构:

Level 1:                         page(4)|+---------+----------+---------+--------+/         /           |          \        \
Level 0:  page(8) <-> page(9) <-> page(10) <-> ... <-> page(20) 

后续文章将开始讨FIL_PAGE_INDEX页内的记录内容。

相关文章:

InnoDB文件物理结构解析2 - FIL_PAGE_INDEX

1. 关于索引组织表 InnoDB使用的是索引组织表(IOT)的方式存储表记录&#xff0c;索引组织表以主键构建一个B-tree的数据结构来存储行记录&#xff0c;行记录存储在树的叶节点内。这与Oracle数据库是不同的&#xff0c;Oracle数据库默认创建的表是堆组织表(HOT)&#xff0c;HOT…...

XML-BEANS compiled schema: Could not locate compiled schema resource 异常处理

使用poi5.2.2生成ppt&#xff0c;生成堆叠图&#xff0c;设置值时抛出异常 XML-BEANS compiled schema: Could not locate compiled schema resource org/apache/poi/schemas/ooxml/system/ooxml/stoverlappercent872etype.xsb (org.apache.poi.schemas.ooxml.system.ooxml.st…...

IOC容器 - Autofac

DI&#xff08;依赖注入&#xff09;&#xff1a;DI&#xff08;Dependency Injection&#xff09;是一种实现松耦合和可测试性的软件设计模式。它的核心思想是将依赖关系的创建与管理交给外部容器&#xff0c;使得对象之间只依赖于接口而不直接依赖于具体实现类。通过依赖注入…...

用i18n 实现vue2+element UI的国际化多语言切换详细步骤及代码

一、i18n的安装 这个地方要注意自己的vue版本和i1n8的匹配程度&#xff0c;如果是vue2点几&#xff0c;记得安装i18n的8版本&#xff0c;不然会自动安装的最新版本&#xff0c;后面会报错哦&#xff0c;查询了下资料&#xff0c;好像最新版本是适配的vue3。 npm install vue-…...

Vue3 :Pinia入门

Vue3 &#xff1a;Pinia入门 Date: May 11, 2023 Sum: Pinia概念、实现counter、getters、异步action、storeToRefs保持响应式解构 什么是Pinia Pinia 是 Vue 的专属状态管理库&#xff0c;可以实现跨组件或页面共享状态&#xff0c;是 vuex 状态管理工具的替代品&#xff0c…...

Java线程池的类型和使用

Java线程池的类型和使用 引言 在并发编程中&#xff0c;线程池是一种非常重要的工具&#xff0c;它可以实现线程的复用&#xff0c;避免频繁地创建新线程&#xff0c;从而提高程序的性能和效率。Java的并发库提供了丰富的线程池功能&#xff0c;本文将介绍Java线程池的类型和…...

QT的信号槽的四种写法和五种链接方式

目录 四种信号槽写法&#xff1a; 五种连接方式&#xff1a; 实例&#xff1a; 常见错误及改正&#xff1a; 错误1: 未连接信号与槽 错误2: 信号和槽参数不匹配 错误3: 未使用Q_OBJECT宏 错误4: 跨线程连接未处理 在Qt中&#xff0c;信号&#xff08;Signal&#xff09…...

Vue+SpringBoot项目开发:后台登陆功能的实现(二)

写在开始:一个搬砖程序员的随缘记录文章目录 一、SpringBoot项目的搭建二、数据库配置1、新建数据库2、新建用户表 三、SpringBoot项目的配置 一、SpringBoot项目的搭建 项目搭建传送门&#xff1a;从零开始&#xff0c;SpringBoot项目快速搭建 二、数据库配置 1、新建数据库…...

arcgis pro 3.0.2 安装及 geemap

arcgis pro 3.0.2 安装及 geemap arcgis pro 3.0.2 安装 arcgis pro 3 版本已经很多了&#xff0c;在网上找到资源就可以进行安装 需要注意的是&#xff1a;有的文件破解文件缺少&#xff0c;导致破解不成功。 能够新建地图就是成功了&#xff01; geemap安装 1.需要进行环…...

oracle插入多表(insert all/first)

1、建测试表 CREATE TABLE EDW_INT (AGMT_NO VARCHAR2(40 BYTE) NOT NULL,AGMT_SUB_NO VARCHAR2(4 BYTE) NOT NULL,NEED_REPAY_INT NUMBER(22,2),CURR_PERIOD NUMBER(4) NOT NULL ); CREATE TABLE EDW_INT_1 (…...

工业以太网交换机-SCALANCE X200 环网组态

1.概述 SCALANCE X200 系列交换机自从2004年8月推入市场&#xff0c;当时交换机只能接入环网&#xff0c;不能做环网管理器。在各个工业现场得到了广泛的应用。2007年5月发布了X200系列新的硬件版本平台&#xff0c;普通交换机可以用HSR&#xff08;高速冗余&#xff09;方法做…...

利用 Splashtop Enterprise 改善公司的网络安全

在我们日益数字化的世界中&#xff0c;对强有力的网络安全措施的需求从未像现在这样迫切。随着组织扩大其数字足迹并采用远程办公解决方案&#xff0c;他们面临着一系列不断变化的挑战。 威胁行为者不断寻找利用漏洞的新方法&#xff0c;这使得企业保持领先地位至关重要。俗话…...

mqbroker.cmd闪退(mqnamesrv.cmd能正常启动)

解决&#xff1a; 用户目录下面store文件&#xff08;如&#xff1a;C:\Users\Administrator\store或C:\Users\你的用户名\store&#xff09;&#xff0c;删除文件里面所有文件&#xff0c;再次启动即可。...

LeetCode--HOT100题(26)

目录 题目描述&#xff1a;142. 环形链表 II&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;142. 环形链表 II&#xff08;中等&#xff09; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返…...

HTTP 请求方法详解

HTTP 请求方法详解 请求方法 请求方法&#xff08;Request Methods&#xff09;是在 HTTP 请求中用于指定对目标资源执行的操作类型。每个请求都需要指定一个请求方法&#xff0c;以告知服务器要执行的操作。 以下是一些常见的 HTTP 请求方法及其主要用途&#xff1a; GET&…...

孤立随机森林(Isolation Forest)(Python实现)

目录 1 简介 2 孤立随机森林算法 2.1 算法概述 2.2 原理介绍 2.3 算法步骤 3 参数讲解 4 Python代码实现 5 结果 1 简介 孤立森林&#xff08;isolation Forest&#xff09;是一种高效的异常检测算法&#xff0c;它和随机森林类似&#xff0c;但每次选择划分属性和划…...

小程序如何自定义分享内容

小程序项目中遇到门票转增功能&#xff0c;用户可将自己购买的门票分享给好友&#xff0c;好友成功领取即得门票一张 1.自定义分享按钮 通过button里的open-type属性里的share参数即自可定义分享按钮 <button open-type"share">分享</button>2.配置分…...

SpringBoot整合WebSocket详解

环境&#xff1a;Springboot3.0.5 WebSocket介绍 WebSocket协议RFC 6455提供了一种标准化的方式&#xff0c;通过一个TCP连接在客户端和服务器之间建立全双工、双向的通信通道。它是一个不同于HTTP的TCP协议&#xff0c;但设计为在HTTP之上工作&#xff0c;使用80和443端口&am…...

伪原创神码ai怎么样【php源码】

这篇文章主要介绍了python汉化补丁包下载&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 火车头采集ai伪原创插件截图&#xff1a; ** Spyder汉化&#xff08;python汉化&…...

Air001基于Keil环境开发,使用airisp串口命令行烧录

Air001基于Keil环境开发&#xff0c;使用airisp串口命令行烧录 有人会有这样的疑惑&#xff0c;使用Keil平台开发&#xff0c;为什么不直接使用CMSIS-DAP直接烧录&#xff0c;还要使用串口方式来去单独烧录&#xff0c;不是我不想&#xff0c;目前使用合宙官方的Air103芯片版本…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...