iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
自我挑戰組

那些Mysql我不知道的事系列 第 5

Innodb資料頁結構-Part1(使用者紀錄、空閒空間、頁面中最小與最大的紀錄)

前文提到頁是Innodb的基本存取單位,一般為16kb,Innodb為了實現功能其實設計了許多不同類型的頁,但我們不管那麼多,今天就只探討我們最關心的儲存記錄的頁(資料頁),官方又叫作索引(index)頁。

資列頁(16kb大小)的結構有7個部分

  1. 使用者紀錄(user records)
  2. 空閒空間(free space)
  3. 頁面中最小與最大的紀錄(infimum+supermum)
  4. 頁面目錄(page directory)
  5. 頁面標頭(page header)
  6. 檔案表頭(file header)
  7. 檔案結尾(file trailer)

使用者紀錄(user records)、空閒空間(free space)、頁面中最小與最大的紀錄(infimum+supermum)

在資料頁內儲存一筆紀錄的流程為先向free space申請空間(一開始生成頁的時候並沒有user records區塊),
再將空間劃分到user records去,當所有的free space都被劃分到user records後,如果還有新紀錄要儲存就要另外生成新的資料頁。

前文提到資料內的標頭資訊很重要,今天要再詳細說明。

heap_no(表示目前紀錄在頁面堆疊中的相對位置)

設計Innodb的工程師把新增的每一筆資料緊密無間的擺放在一起,稱其為堆疊(heap)。

每筆紀錄在堆疊中的相對位置稱為heap_no(是一個數字 ex:2),在頁面前面的heap_no值相對較小,在頁面後面的heap_no值相對較大,每新申請一筆紀錄的儲存空間時,該筆紀錄比物理位置在它前面的那筆紀錄heap_no值大1。

還有一個地方要注意,增加一筆紀錄到新生成的頁面時,頁面會自動再增加兩筆虛擬紀錄(infimum+supermum頁面中最小與最大的紀錄,不論插入多少紀錄也不管其主鍵值大小,infimum就是頁面中最小的紀錄,supermum就是頁面中最大的紀錄,這是規定!記住就對了!)

所以當我們插入兩筆資料時

mysql> insert into ryan_demo_table(c1,c2,c3,c4) values ('aaaa','bbb','cc','d'),('eeee','fff',NULL,NULL);
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from ryan_demo_table;
+------+-----+------+------+
| c1   | c2  | c3   | c4   |
+------+-----+------+------+
| aaaa | bbb | cc   | d    |
| eeee | fff | NULL | NULL |
+------+-----+------+------+
2 rows in set (0.00 sec)

這兩筆紀錄heap_no值分別會是2跟3(頁面自動再增加2筆虛擬紀錄infimum[heap_no:0]+supermum[heap_no:1]),而不是0跟1。

next_record

這屬性顧名思義就是用來找到下筆紀錄的,存放的是與下筆紀錄的真實距離(ex:3 從該筆紀錄往後找3個位元組會找到下筆紀錄),對於資料結構有點概念就會知道它是鏈結串列(透過一筆紀錄找到下一筆紀錄)。這邊要注意的是下筆紀錄並不是插入順序的下筆紀錄,而是資料照著主鍵值大小排序後,排在其後的下筆紀錄。
而infimum的下筆紀錄就是user records中主鍵最小的那筆,user records中主鍵最大那筆的下筆紀錄就是supermum,supermum的下筆紀錄就是0。

deleted_flag

先認知Innodb儲存紀錄的結構就是一個按照主鍵大小排序的單向鏈結串列。
當我們刪掉其中一筆資料A,資料改變的只有3個地方(不包含n_owned的部分,這之後會再說明)。

  1. 資料A並不會從儲存空間中移除,而是deleted_flag變成1
  2. 資料A的next_record變成0
  3. 指向資料A的紀錄變成指向本來資料A的next_record

當資料頁出現多筆被刪除的紀錄,可以透過next_record屬性組成一個垃圾鏈結串列。
再來還有一個值得注意的是如果我們之後新增資料,則會重複利用deleted_flag變成1的刪除紀錄,並不會重新申請新的儲存空間唷。


上一篇
認識Innodb儲存引擎
下一篇
Innodb資料頁結構-Part2(頁面目錄、頁面表頭、檔案表頭、檔案結尾)
系列文
那些Mysql我不知道的事30

尚未有邦友留言

立即登入留言