原文地址: blog.jcole.us/2013/01/03/…
在數據存儲模型中,一般有「空間」這個概念,在 MySQL 中被稱爲「表空間」,有時候在 InnoDB 中也被稱爲「文件空間」。一個空間可能由一個操做系統中的多個實際文件組成(例如 ibdata1, ibdata2 等等),實際上只是一個邏輯文件 - 多個文理文件被當作一個鏈接在一塊兒的文件處理。node
InnoDB 中每一個空間都被分配了一個 32 位的無符號整型空間 ID,這個 ID 被用來在不一樣的地方引用指向這個空間。InnoDB 老是有一個「系統空間」,他的空間 ID 是 0。系統空間用於保存 InnoDB 的一系列元數據的記錄。經過 MySQL,InnoDB 目前只支持「一個表一個文件」空間形式的額外空間,這將爲每個 MySQL 表建立 .ibd 文件。從內部來看,這個 .ibd 文件實際是一個能夠容納多個表的完整的空間,可是在 MySQL 的實現中,它只能包含一個表。數組
頁
=緩存
每一個空間被切分紅了頁,通常每頁 16 KiB(也能夠經過在編譯時指定 UNIV_PAGE_SIZE
修改,或者開啓了 InnoDB 壓縮)。空間中的頁會被分配一個 32 位的頁碼,這個頁碼被稱爲偏移,其實這個頁碼就是從空間地址開頭的頁偏移。因此,第 0 頁位於文件偏移 0 的位置,第 1 頁位於文件偏移 16384 的位置,以此類推。可能這裏有些人會想起來,InnoDB 的數據大小限制是 64 TiB,這個實際上是每一個空間的大小限制。由於頁碼是一個 32 位的無符號整型,而且默認的頁大小是 16 KiB,這樣空間最大大小是 2^32 * 16 KiB = 64 TiB數據結構
頁的結構以下:spa
每一頁都有一個 38 字節的 FIL
頭部和一個 FIL
尾部(FIL
這個名字其實就是出自 「file」的簡寫)。頭部包含一個表示頁類型的字段,這個類型決定了頁的剩下部分的結構。 FIL
頭部和 FIL
尾部結構以下所示:操作系統
FIL
頭部以及尾部包含如下結構:指針
一個空間文件是不少頁(最多 2^32)的聚合連接,爲了更高效的管理,頁被聚合成不少個 1 MiB 大小的塊(64 個連續頁,默認頁大小是 16 KiB),這個塊被稱爲「區」(extent)。不少結構只經過引用區來在一個空間中分配頁日誌
InnoDB 須要作一些元數據記錄,來追蹤全部頁,區以及空間自己。code
空間中的第一頁是 FSP_HDR
(文件空間頭頁)。FSP_HDR
頁包含一個 FSP
結構,記錄像是空間的大小,空閒區、碎片區和滿區的列表等數據(未來我會寫一篇詳細的關於空閒空間管理介紹的文章)。 一頁 FSP_HDR
只有夠保存 256 個區(至關於 16384 頁,256 MiB)信息的空間,因此每 16384 頁以後,都須要額外記錄這些頁信息的空間。XDES
頁和 FSP_HDR
頁的結構是相同的,只是在 XDES
中 FSP
佔用的存儲都是被 0 填充的。這些額外的頁會隨着空間文件的增加而自動分配。blog
INODE
頁用來保存文件段(Segmentation,包含一組區以及一個只會單獨分配的碎片區的數組)的列表。每一個 INDOE
頁能夠保存 85 個 INODE
元素,每一個索引須要兩個 INODE
元素(未來我會寫一篇詳細的關於 INDOE 元素內容和文件區的文章)。
IBUF_BITMAP
頁保存關於插入緩存的信息,不在本系列的討論範圍內。
系統空間(第 0 個空間)比較特殊,包含許多按固定頁碼分配的頁面,以存儲對 InnoDB 操做相當重要的大量信息。系統空間與任何其餘空間同樣,也須要 FSP_HDR
, IBUF_BITMAP
,Inode
這三個頁面做爲頭三頁。這以後,與其餘頁面有點區別。
SYS
類型:與插入緩存相關的頭信息。INDEX
類型:用於插入緩衝的索引結構的根頁。TRX_SYS
類型:與 InnoDB 事務系統的操做相關的信息,例如最新的事務ID、MySQL二進制日誌信息和雙寫緩衝區範圍的位置。SYS
類型:第一個回滾段頁。根據須要分配其餘頁(或整個區段)來存儲回滾段數據。SYS
類型:與數據字典相關的頭信息,包含組成數據字典的索引的根頁碼。這些信息可以找到任何其餘索引(表),因爲它們的根頁碼就存儲在這個數據字典中。其餘頁按需分配給索引、回滾段、撤消日誌(undo logs)等.
InnoDB提供了「每一個表一個文件」模式,該模式將爲每一個 MySQL 表建立一個文件(如上所述其實是一個空間)。可能叫作「每一個表一個空間」更合適一些。每一個表都會建立 .ibd
文件,它的結構以下:
忽略快速添加索引(即在運行時添加索引),在必需的3個初始頁以後,空間中分配的下一個頁面將是表中每一個索引的根頁,按表建立中定義的索引順序排列。第 3 頁將是彙集索引的根,第 4 頁將是第一個二級索引的根,以此類推。
因爲 InnoDB 的大部分元數據結構都存儲在系統空間中,所以在「每一個表一個空間」中分配的大多數頁都是 INDEX
類型的並存儲表數據。