InnoDB文件物理结构解析7 - FIL_PAGE_SDI

在数据库系统中,通常包含数据字典(data dictionary)用于记录数据库对象的元数据(表,分区,触发器,存储过程,函数的定义),我们可以通过information_schema(i_s)数据库下的视图(view)或者SHOW语句来访问数据字典。例如,可以通过show create table sakila.film语句获取film表的DDL语句。或者使用的innodb_indexes, innodb_tables,… 视图获取表元数据信息。 在MySQL 8.0之前的版本,数据字典信息存储在基于文件的元数据文件,不支持事务的表,和存储引擎相关的数据字典中。

在MySQL 5.7版本,sakila.film表,除了film.ibd文件,还有film.frm和film.TRG文件。.TRG文件保存了film表相关的触发器元数据,而.frm文件则存储了film表的元数据,包括字段名,字段数据类型等信息。基于文件的数据字典不支持事务,在管理上有一系列的问题,因此从MySQL8.0版本开始,MySQL引入一个基于事务的数据字典来存储数据对象的信息。详细请参考:
https://minervadb.com/index.php/2018/06/11/mysql-8-0-data-dictionary/
https://dev.mysql.com/doc/refman/8.0/en/data-dictionary.html

Data dictionary tables are created in a single InnoDB tablespace named mysql.ibd, which resides in the MySQL data directory. The mysql.ibd tablespace file must reside in the MySQL data directory and its name cannot be modified or used by another tablespace.

注意:是不允许通过SQL语句直接访问数据字典的:

root@localhost [testcase]> select * from mysql.tables;
ERROR 3554 (HY000): Access to data dictionary table ‘mysql.tables’ is rejected.

但可以通过一些方法绕过限制: https://lefred.be/content/mysql-8-0-data-dictionary-tables-and-why-they-should-stay-protected/

其中一个重要的改变就是,从8.0版本开始,MySQL废弃了.frm文件(还包括.par,.TRN,.TRG, .isl,db.opt,ddl_log.log ),MySQL使用字典信息序列化格式(serialized form)来存储数据字典,这部分数据称为serialized dictionary information (SDI),MySQL将SDI存放对应表的表空间中,并引入新的Page如:FIL_PAGE_SDI来存放SDI的数据。对于非InnoDB表,如MyISAM,SDI会存放在.sdi文件中(一种json格式的文本文件)。MySQL还提供了ibd2sdi外部命令用于从表空间文件(ibd)中读取的SDI信息。

我们可以把SDI记录看成是一张普通表,可以把FIL_PAGE_SDI页当做FIL_PAGE_INDEX (ClusteredKeyLeafPage)来解析,而SDI"表"的定义伪代码如下:

CREATE TABLE SID {type bytes(2) not null,  // 对应ibd2sdi的-t, --type=#参数,请参考ibd2sdi命令官方文档。id bytes(4) not null,     //  对应ibd2sdi的-i, --id=#参数,请参考ibd2sdi命令官方文档。/*DB_TRX_ID bytes(6) not null,*//*DB_ROLL_PTR bytes(7) not null,*/uncomp_len bytes(5) not null, // zip_data解压后的长度(字节数);comp_len bytes(6) not null,  // zip_data的长度(字节数);zip_data bytes(variable-length) not null, //通过zip压缩后的SDI记录内容;PRIMARY KEY (type, id)
}

FIL_PAGE_SDI页的位置位于ibd文件的page(3),我们通过案例来解析该页的内容:

public class SdiPage1 {public static void main(String[] args) throws Exception {String fileName = "D:\\Data\\mysql\\8.0.18\\data\\sakila\\film.ibd";try (IbdFileParser parser = new IbdFileParser(fileName)) {SdiPage page = (SdiPage) parser.getPage(3);List<SdiRecord> records = page.getUserRecords();StringBuilder buff = new StringBuilder();int rows = 0;for(SdiRecord record: records) {byte[] unZipData = record.getUnZipDataRaw();byte[] zipData = record.getZipDataRaw();String json = toPretty(new String(unZipData));String format = "%11s : ";buff.append("\n*************************** ").append(++rows).append(". row ***************************\n").append(String.format(format, "type")).append(record.getType()).append("\n").append(String.format(format, "id")).append(record.getId()).append("\n").append(String.format(format, "DB_TRX_ID")).append(ParserHelper.toHexString(record.getTrxIdRaw())).append("\n").append(String.format(format, "DB_ROLL_PTR")).append(ParserHelper.toHexString(record.getRollPrtRaw())).append("\n").append(String.format(format, "unzip_len")).append(record.getUncompressedLen()).append(" , actual : ").append(unZipData.length).append("\n").append(String.format(format, "zip_len")).append(record.getCompressedLen()).append(" , actual : ").append(zipData.length).append("\n").append("\n*************************** Content ***************************\n").append(json).append("\n");}System.out.println(buff);}}public static String toPretty(String jsonString) {JsonElement jsonElement = JsonParser.parseString(jsonString);Gson gson = new GsonBuilder().setPrettyPrinting().create();String prettyJson = gson.toJson(jsonElement);return prettyJson;}
}
/*
程序输出:
*************************** 1. row ***************************type : 1id : 521DB_TRX_ID : 000000738097
DB_ROLL_PTR : 020000028a15a9unzip_len : 16801 , actual : 16801zip_len : 1884 , actual : 1884*************************** Content ***************************
{"mysqld_version_id": 80018,"dd_version": 80017,"sdi_version": 80016,"dd_object_type": "Table","dd_object": {"name": "film","mysql_version_id": 80018,"created": 20210319003202,"last_altered": 20210319003202,...
}}*************************** 2. row ***************************type : 2id : 392DB_TRX_ID : 00000073803d
DB_ROLL_PTR : 82000001230535unzip_len : 372 , actual : 372zip_len : 233 , actual : 233*************************** Content ***************************
{"mysqld_version_id": 80018,"dd_version": 80017,"sdi_version": 80016,"dd_object_type": "Tablespace","dd_object": {"name": "sakila/film","comment": "","options": "encryption\u003dN;","se_private_data": "flags\u003d16417;id\u003d387;server_version\u003d80018;space_version\u003d1;state\u003dnormal;","engine": "InnoDB","files": [{"ordinal_position": 1,"filename": ".\\sakila\\film.ibd","se_private_data": "id\u003d387;"}]}
}    
*/

与ibd2sid命令输出比对,程序解析符合预期,解析细节可以看SdiPage.class,做法就是当作ClusteredKeyLeafPage来解析,zip_data通过JDK的java.util.zip.Inflater解压。到此ibd解析系列告一段落,未来如果精力允许,而且知识储备足够,会挑战一下redo或者undo表空间结构的解析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/36811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【爱书不爱输的程序猿】CPOLAR+HFS,低成本搭建NAS

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 通过HFS低成本搭建NAS&#xff0c;并内网穿透实现公网访问 - cpolar 极点云 前言1.下载安装cpolar1.1 设置HFS访客1.2 虚拟文件系统 2. 使用cpolar建立一条内网穿透数据隧道2.1 保留…

(三) 搞定SOME/IP通信之CommonAPI库

本章主要介绍在SOME/IP通信过程中的另外一个IPC通信利剑,CommonAPI库,文章将从如下几个角度让读者了解什么是CommonAPI, 以及库在实际工作中的作用 SOME/IP通信之CommonAPI CommonAPI库是什么CommonAPI库的编译写个Demo实战一下CommonAPI库是什么 CommonAPI是GENIVI组织开发…

推出 Elasticsearch 查询语言 (ES|QL)

作者&#xff1a;Costin Leau 我很高兴地宣布&#xff0c;经过大约一年的开发&#xff0c;Elasticsearch 查询语言 (ES|QL) 已准备好与世界共享&#xff0c;并已登陆 Elasticsearch 存储库。 ES|QL 是 Elasticsearch 原生的强大声明性语言&#xff0c;专为可组合性、表现力和速…

Django-配置邮箱功能(一):使用django自带的发送邮件功能

一、获取邮箱授权码 以QQ邮箱为例子&#xff1a; 1、进入到设置&#xff0c;找到账户 2、开启POP3等服务&#xff0c;点击管理服务 3、进入管理服务&#xff0c;生成授权码 4、按照要求发送短信就可以了 5、将授权码复制保存&#xff0c;离开界面就看不到了 二、django项目中…

2023上半年京东手机行业品牌销售排行榜(京东数据平台)

后疫情时代&#xff0c;不少行业都迎来消费复苏&#xff0c;我国智能手机市场在今年上半年也实现温和的复苏&#xff0c;手机市场的出货量回暖。 根据鲸参谋平台的数据显示&#xff0c;2023年上半年&#xff0c;京东平台上手机的销量为2830万&#xff0c;环比增长约4%&#xf…

剑指 Offer ! 61. 扑克牌中的顺子

参考资料&#xff1a;力扣K神的讲解 剑指 Offer 61. 扑克牌中的顺子 简单 351 相关企业 从若干副扑克牌中随机抽 5 张牌&#xff0c;判断是不是一个顺子&#xff0c;即这5张牌是不是连续的。2&#xff5e;10为数字本身&#xff0c;A为1&#xff0c;J为11&#xff0c;Q为12&…

引入三阶失真的非线性放大器的模拟输出及使用中值滤波器去除峰值研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【C/C++】STL queue 非线程安全接口,危险!

STL 中的 queue 是非线程安全的&#xff0c;一个组合操作&#xff1a;front(); pop() 先读取队首元素然后删除队首元素&#xff0c;若是有多个线程执行这个组合操作的话&#xff0c;可能会发生执行序列交替执行&#xff0c;导致一些意想不到的行为。因此需要重新设计线程安全的…

JVM 内存结构

1、方法区&#xff08;线程共享&#xff09; 存储静态变量(静态方法、变量、代码块)、常量池、类信息 2、堆信息&#xff08;线程共享&#xff09; 存储实例对象&#xff0c;例如 new 出来的对象信息 A a1 new A() 3、虚拟机栈&#xff08;线程隔离&#xff09; 每个线程的都有…

三、MySql表的操作

文章目录 一、创建表&#xff08;一&#xff09;语法&#xff1a;&#xff08;二&#xff09;说明&#xff1a; 二、创建表案例&#xff08;一&#xff09;代码&#xff1a;&#xff08;二&#xff09;说明&#xff1a; 三、查看表结构&#xff08;一&#xff09;语法&#xff…

docker相关命令总结(停止、重启、重加载配置文件)

常用命令 # 配置 Docker 守护进程的行为和参数 vi /etc/docker/daemon.json# 停止docker服务 sudo systemctl stop docker# 启动 Docker 服务&#xff1a; sudo systemctl start docker# 重新加载systemd守护程序的配置文件&#xff0c;不会重启服务&#xff08;配置文件&…

Go语言template模板语法

Go语言模板语法 文章目录 <center> Go语言模板语法连接前后端的符号: {{}}注释管道(pipeline)变量条件判断range 关键字with 关键字比较函数自定义函数嵌套模板模板继承 连接前后端的符号: {{}} 模板语法都包含在{{}}之中,其中{{.}}中的.表示当前对象.在传入一个结构体对…

sql-libs靶场-----0x00、环境准备

文章目录 一、PhPstudy下载、安装二、Sqli-libs下载、搭建三、启用Sqli-libs phpstudy地址&#xff1a;https://www.xp.cn/ sqli-libs地址&#xff1a;https://github.com/Audi-1/sqli-labs 一、PhPstudy下载、安装 1、下载–解压–安装&#xff0c;安装完成如下图 2、更换php…

【学习笔记】[AGC021F] Trinity

有点难&#x1f605; 考虑加入每一列&#xff0c;发现我们只关心当前还未确定的行的数目 有点难算&#x1f605; 设 d p i , j dp_{i,j} dpi,j​表示有 i i i列&#xff0c;其中 j j j行未确定的方案数。钦定每一列至少有一个黑色格子。 d p i , j j ( j 1 ) 2 d p i − 1…

IGV.js 的完全本地化运行探索

问题及解决方法 IGV.js 完全本地化是为了合规&#xff0c;不使用外网的情况下查看基因组。不联网需要下载 genomes.json 文件及其中的内容之外&#xff0c;还需要修改 igv.js本身&#xff0c;防止5s超时后才显示网页内容。修改的关键词是: genomes.json&#xff0c;改为本地的…

Leetcode-每日一题【剑指 Offer 13. 机器人的运动范围】

题目 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&#xff0c;也不能进入行坐标和列坐标的数位之和大于k的格子。例…

一个简单实用的线程池及线程池组的实现!

1.线程池简介 线程池&#xff0c;顾名思义&#xff0c;就是一个“池子”里面放有多个线程。为什么要使用线程池呢&#xff1f;当我们编写的代码需要并发异步处理很多任务时候&#xff0c;一般的处理办法是一个任务开启一个线程去处理&#xff0c;处理结束后释放线程。可是这样…

【QT】窗口通过dragEnterEvent和dropEvent拖拽导入文件

【QT】窗口通过dragEnterEvent和dropEvent拖拽导入文件 界面允许接受拖拽 在界面的构造函数中设置接受拖拽放置文件 setAcceptDrops(true); 拖拽进入、放下事件 dragEnterEvent函数对拖动的文件进行过滤&#xff0c;如果不符合过滤条件按将无法拖拽进入窗口 dropEvent函数…

支付总架构解析

一、支付全局分层 一笔支付以用户为起点&#xff0c;经过众多支付参与者之后&#xff0c;到达央行的清算账户&#xff0c;完成最终的资金清算。那么我们研究支付宏观&#xff0c;可以站在央行清算账户位置&#xff0c;俯视整个支付金字塔&#xff0c;如图1所示&#xff1a; 图…

[保研/考研机试] KY135 又一版 A+B 浙江大学复试上机题 C++实现

题目链接&#xff1a; KY135 又一版 AB https://www.nowcoder.com/share/jump/437195121691736185698 描述 输入两个不超过整型定义的非负10进制整数A和B(<231-1)&#xff0c;输出AB的m (1 < m <10)进制数。 输入描述&#xff1a; 输入格式&#xff1a;测试输入包…