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.pswp.cn/news/36811.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36811.shtml
英文地址,請注明出處:http://en.pswp.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;測試輸入包…