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

本文讨论FIL_PAGE_INDEX页的可回收垃圾记录(Garbage/Deleted Records),当我们删除某一条记录(delete from …)时,通常InnoDB并不会在物理存储上进行完全删除,而是在记录上置一个删除标志位,我们称这些行记录为垃圾记录,删除标志位位于对应记录的Extra Bytes中。与正常的记录(User Records)类似,InnoDB在页内也有一个单向链表将可回收垃圾记录串在一起,用户记录是从Infimum Record开始,到Supremum Record结束, 而可回收垃圾记录则是从"FIL_PAGE_INDEX"页中的"INDEX Header"中的PAGE_FREE (First Garbage Record Offset) 开始,到最后一条垃圾数据结束(next_offset=0,指向自己)。记录遍历的方式都是一样的。

sakila数据库是MySQL官方的案例库,这里介绍一下获取方法,打开链接: https://dev.mysql.com/doc/index-other.html,然后找到"Example Databases"章节,即可获取下载和相关文档链接。

上代码,解析Garbage Records:

/*
在数据库中执行删除操作:
root@localhost [sakila]> set foreign_key_checks = 0; --> 因为sakila有外键约束, 为了简化删除, 先在会话中禁用外键检查;
Query OK, 0 rows affected (0.00 sec)root@localhost [sakila]> delete from sakila.film where film_id in (646, 656, 666); --> 删除3条记录;
Query OK, 3 rows affected (0.01 sec)
*/public class IdxPage5 {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)) {// 通过上文"InnoDB文件物理结构解析4"可知,page(14)包含film_id=(565, 668)之间的数据;Page page = parser.getPage(14);// System.out.println(ParserHelper.hexDump(page.getPageRaw()));ClusteredKeyLeafPage leafPage = new ClusteredKeyLeafPage(page.getPageRaw(), page.getPageSize());List<ClusteredKeyLeafRecord> garbageRecords = leafPage.getUserRecords(IdxPage3.getFilmTableMeta());StringBuilder buff = new StringBuilder();for (ClusteredKeyLeafRecord record : garbageRecords) {List<RecordField> fields = record.getRecordFields();buff.append("\n ==> Extra: deleted = ").append(record.getDeletedFlag()).append("; next offset = ").append(record.getNextRecordOffset()).append(" <==\n");for (RecordField field : fields) {buff.append(String.format("%20s", field.getName())).append(": ").append(field.getContent()).append("\n");}}System.out.println(buff);}}
}/* 
程序执行结果:==> Extra: deleted = true; next offset = -1432 <==film_id: 666DB_TRX_ID: 00000000843cDB_ROLL_PTR: 01000001321526title: PAYCHECK WAITdescription: A Awe-Inspiring Reflection of a Boy And a Man who must Discover a Moose in The Sahara Desertrelease_year: 2006language_id: 1
original_language_id: nullrental_duration: 4rental_rate: 4.99length: 145replacement_cost: 27.99rating: PG-13special_features: [Commentaries, Deleted Scenes]last_update: 2006-02-15T05:03:42==> Extra: deleted = true; next offset = -1489 <==film_id: 656DB_TRX_ID: 00000000843cDB_ROLL_PTR: 010000013214c7title: PAPI NECKLACEdescription: A Fanciful Display of a Car And a Monkey who must Escape a Squirrel in Ancient Japanrelease_year: 2006language_id: 1
original_language_id: nullrental_duration: 3rental_rate: 0.99length: 128replacement_cost: 9.99rating: PGspecial_features: [Trailers, Deleted Scenes, Behind the Scenes]last_update: 2006-02-15T05:03:42==> Extra: deleted = true; next offset = 0 <==film_id: 646DB_TRX_ID: 00000000843cDB_ROLL_PTR: 01000001321466title: OUTBREAK DIVINEdescription: A Unbelieveable Yarn of a Database Administrator And a Woman who must Succumb a A Shark in A U-Boatrelease_year: 2006language_id: 1
original_language_id: nullrental_duration: 6rental_rate: 0.99length: 169replacement_cost: 12.99rating: NC-17special_features: [Trailers, Deleted Scenes, Behind the Scenes]last_update: 2006-02-15T05:03:42
*/

程序输出和我们预想的一样,记录虽然被delete语句删除了,但是数据还是保留在页内的。只是Extra Bytes的delete flag被置为true,最后一条被删除的记录指向的不是"Supremum Record",而是自己(next offset = 0)。

案例中获取删除数据用到了ClusteredKeyLeafPage的getGarbageRecords()方法,与获取普通用户记录的getUserRecords()方法的唯一不同是遍历记录的开始位置不同:

public class ClusteredKeyLeafPage {public List<ClusteredKeyLeafRecord> getUserRecords(TableMeta tableMeta) {int pos = getSystemRecords().getInfimumNextRecordPos(); return iterateRecordInPage(tableMeta, pos);}public List<ClusteredKeyLeafRecord> getGarbageRecords(TableMeta tableMeta) {int pos = getIndexHeader().getFirstGarbageOffset();return iterateRecordInPage(tableMeta, pos);}private List<ClusteredKeyLeafRecord> iterateRecordInPage(TableMeta tableMeta, int firstRecordPos) {//...// 遍历结束的条件if (recCount > maxRecs || nextOffset == 0 || nextRecord == SUPREMUM_EXTRA_END_POS) {break;}//}
}	

更多测试情况:

  • 如果执行的是"truncate sakila.film",该方法是无效的,因为整个ibd文件的存储空间会被"重置"(文件会变小,没有page(14)),全表删除(“delete from sakila.film”)通常不会,但也有特例,当一个表的数据量非常小(索引深度小于1),所有的行都在一个(Leaf) Page时,观察到全表删除和truncate一样,整个页的记录数据会被清掉(置为00),可以通过hexdump确认。

  • 在删除整个页内的记录时,记录虽然不会被清掉,但观察到会有部分删除记录在User Record链表内的情况。

最后,介绍一个通过hexdump命令查看某个页内容的方法:

# 假设我们要看page(4),Page的大小为16KB(16384字节);
# 那么page(4)的起始位置为 4 * 16384=65536,读取长度为16384;
# 所以命令hexdump的命令为:
[think@TP-T470 sakila]$ hexdump --skip 65536 --length 16384 -C -v film2.ibd

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

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

相关文章

嵌入式Qt开发—Excel表格数据导出

有一个嵌入式Excel表格数据导出的需求&#xff1a;应用软件运行于嵌入式Linux平台上&#xff0c;在设备运行过程中&#xff0c;存储了许多数据&#xff0c;这些数据想以表格的形式导出。考虑到Windows平台的普遍性&#xff0c;需要将数据以excel表格形式导出&#xff0c;故选择…

python库打包

一、背景 想让自己写的python库可以使用pip install xxx安装。 二、环境准备 注册PYPI账号已经写好的能正常使用的库/方法/项目&#xff08;可以本地调用&#xff09;安装依赖库setuptools和twinw pip install setuptools pip install twine # 简化将库发布到PYPI流程的工…

“中国软件杯”飞桨赛道晋级决赛现场名单公布

“中国软件杯”大学生软件设计大赛是由国家工业和信息化部、教育部、江苏省人民政府共同主办&#xff0c;是全国软件行业规格最高、最具影响力的国家级一类赛事&#xff0c;为《全国普通高校竞赛排行榜》榜单内赛事。今年&#xff0c;组委会联合百度飞桨共同设立了“智能系统设…

C++11之后的C++标准特性宏定义方便功能特性测试

C是一个庞大的编程语言体系&#xff0c;它的高效性是可以直接连接硬件系统&#xff0c;它的灵活性是不断迭代完善的通用语义机制&#xff0c;当下C的发展演进可谓一路狂奔。不同应用中需要知道C对应的平台或者版本的功能特性&#xff0c;标准库信息、C编译器特性等&#xff0c;…

基于PHP的轻量级博客typecho

本文完成于 5 月中旬&#xff0c;发布时未在最新版本上验证&#xff1b; 什么是 typecho &#xff1f; Typecho 是一款基于 PHP 的博客软件&#xff0c;旨在成为世界上最强大的博客引擎。Typecho 在 GNU 通用公共许可证 2.0 下发布。支持多种数据库&#xff0c;原生支持 Markdo…

24届近5年南京大学自动化考研院校分析

今天给大家带来的是南京大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京大学 学校简介 南京大学是一所历史悠久、声誉卓著的高等学府。其前身是创建于1902年的三江师范学堂&#xff0c;此后历经两江师范学堂、南京高等师范学校、国立东南大学、国立第四中…

JS 删除的是最后一页的最后一条,页码设置逻辑

删除的场景&#xff1a; 解决思路&#xff1a; 1、计算操作后的总页数 2、删除成功之后的总页数与当前总页数进行比较 3、如果删除成功之后的总页数比小于当前总页数&#xff0c;需要把当前页码减去1&#xff1b;否则&#xff0c;直接进行列表数据的请求 代码实现 /*总条数…

VBA 学习笔记1 对象以及属性

目录 1 取得VBA对象1.1 取得工作簿对象1.2 取得工作表对象1.3 取得单元格对象1.4 取得对象的属性1.5 文档的方法1 进入vba 界面 方式之一&#xff1a; 快捷键&#xff1a;ALTERF11 运行方式之一&#xff1a; 进入vba界面&#xff0c;点击绿色三角符号 1 取得VBA对象 1.1 取得…

DAY21

题目一 给定三个字符串str1、str2和aim&#xff0c; 如果aim包含且仅包含来自str1和str2的所有字符&#xff0c;而且在aim中属于str1的字符 之间保持原来在str1中的顺序&#xff0c;属于str2的字符之间保持原来在str2中的顺序&#xff0c;那么称aim是str1和str2的交错组成。实…

Springboot-Retrofit HTTP工具框架快速使用

在SpringBoot项目直接使用okhttp、httpClient或者RestTemplate发起HTTP请求&#xff0c;既繁琐又不方便统一管理。 因此&#xff0c;在这里推荐一个适用于SpringBoot项目的轻量级HTTP客户端框架retrofit-spring-boot-starter&#xff0c;使用非常简单方便&#xff0c;同时又提供…

约数个数(质因子分解)

思路&#xff1a; &#xff08;1&#xff09;由数论基本定理&#xff0c;任何一个正整数x都能写作&#xff0c;其中p1,p2..pk为x的质因子。 &#xff08;2&#xff09;由此可以推断&#xff0c;要求一个数约数的个数&#xff0c;注意到约数就是p1,p2...pk的一种组合&#xff…

日常BUG—— SpringBoot项目DEBUG模式启动慢、卡死。

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 我们调试程序时&#xff0c;需要使用DEBUG模式启动SpringBoot项目&#xff0c; 有时候会发…

convert Auto-Login (cwallet.sso) Wallet into a PKCS12 compliant Wallet

一步不行吗 &#xff1f; 1. If $JAVA_HOME is not set: a)For FMW 11g components associated with a WebLogic Domain or a FMW 12c Collocated OHS install run: $MIDDLEWARE_HOME/user_projects/domains/<domain>/bin/setDomainEnv.sh b) For FMW 11g Standalone…

侧滑置顶,取消置顶

第一步:布局 <?xml version"1.0" encoding"utf-8"?> <com.ddmh.magic.camera.ui.widget.SwipeMenuLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"…

SQL | 使用通配符进行过滤

6-使用通配符进行过滤 6.1-LIKE操作符 前面介绍的所有操作符都是通过已知的值进行过滤&#xff0c;或者检查某个范围的值。但是如果我们想要查找产品名字中含有bag的数据&#xff0c;就不能使用前面那种过滤情况。 利用通配符&#xff0c;可以创建比较特定数据的搜索模式。 …

selenium 爬虫

selenium 可以动态爬取网页数据&#xff0c;就像真实用户操作浏览器一样&#xff0c;从终端用户的角度测试应用程序&#xff0c;WebDriver通过原生浏览器支持或者浏览器扩展直接控制浏览器 webdriver下载 因为selenuim对浏览器的版本存在兼容问题&#xff0c;顾需要针对指定浏…

SAP系统是什么呢?它有哪些优势?

SAP系统是全球知名的企业资源规划&#xff08;ERP&#xff09;解决方案供应商。它集成了财务、供应链管理、人力资源管理、销售和客户关系管理等多个功能模块&#xff0c;为企业提供全面、集成的管理体验。SAP系统已成为各行各业企业管理的智慧选择&#xff0c;极大地提升了管理…

c++ 有元

友元分为两部分内容 友元函数友元类 友元函数 问题&#xff1a;当我们尝试去重载operator<<&#xff0c;然后发现没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作 数了。…

如何在vue3中加入markdown语法

1、首先需要安装 md-editor-v3 yarn add md-editor-v3 或者是在vue图形化界面中直接搜索 md-editor-v3 进行安装。 2、引入该编辑页 引入可以参考这个&#xff0c;根据自己的需求进行修改和添加。 <template><md-editor v-model"text"/> </templat…

基于dbn+svr的交通流量预测,dbn详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN+SVR的交通流量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN+SVR用于交通流量预测…