關於INNODB SYSTEM RECORD infimum和supremum的學習和實驗研究

gaopengtttt發表於2016-03-28
關於INNODB SYSTEM RECORD infimum和supremum的學習和實驗研究

接上一篇 
http://blog.itpub.net/7728585/viewspace-2063921/
關於MYSQL INNODB index page header學習和實驗總結 

所用到的工具是自己寫的mysqlblock和bcview,
我放到了百度雲盤

供大家下載和使用

接下來就是INDEX SYSTEM RECORDS,就是infimum和supremum
如前面所介紹的,這兩個系統記錄是每個INNODB 塊必須的,
用來標示記錄的開頭和結束
及infimum.next_offset--->記錄1 記錄1.next_offset--->記錄2 記錄1.next_offset--->記錄n 記錄n.next_offset--->supremum
我們知道在一個C語言中最後一個連結串列的NEXT指標指向的NULL空指標,那麼這裡SUPREMUM實際就是NULL空指標及0
他們位置固定在塊的94-120位元組,其中94-107為infimum 相關資訊,而107到120為supremum相關資訊

info flags              4bits
number of records owned 4bits
order                  13bits
record type             3bits
next record offset      2bytes
"infimum\0"             8bytes (C語言陣列以\0表示結尾)
以上是infimum固定資訊
info flags              4bits
number of records owned 4bits
order                   13bits
record type             3bits
next record offset      2bytes
"supremum"              8bytes
以上是supremum固定資訊

我們同樣適用bcview來檢視infimum資訊,當然檢視的還是塊3(0開頭實際是第4個塊)
bcview km1.ibd 16 94 16|more

current block:00000003--Offset:00094--cnt bytes:13--data is:0100020041696e66696d756d00
1、info flags
這4位(4bits)標示是一個行標識,其中binary 0001表示最小的行,其中binary 0010表示是刪除的行,而infimum和supremum行在我測試資料庫中為binary 0000
2、number of records owned 
這4位(4bits)表示在本page directory(槽)中的記錄數,關於槽的概念後面詳細探討
3、order
這13位(13bits)表示記錄插入到塊中順序,INFIMUM恆等於0而SPREMUM恆等於1,而資料行的ORDER從2開始
4、record type
這3位(3bits)表示記錄的型別,supermum恆等於3及binary 011,infimum恆等於2及binary010,節點指標為1及001,資料行為000
5、next record offset 
這2個位元組 在INFIMUM中表示的是第一個行的偏移量這個偏移量是當前記錄的位置+offset,這個offset直接指向了資料而相關的行頭在offset-n開始n為行頭的開銷。
當然supermum為的偏移量就是NULL空指標了。
6、"infimum\0" OR "supremum" 
這沒什麼好解釋的就是實際的ASCII值


我們還是適用我寫工具mysqlblock和bcview進行驗證


[root@hadoop1 test]# mysqlblock km1.ibd -d
***************************************************
USEAGE: mysqlblock datafile -t/-d                  
This small tool used in study and test database,not
uesd on online database!                           
This tool is used to find how many blocks and types
in specified datafile,Exp:how many undo block in d 
ata file!                                          
QQ:2238980                                         
***************************************************
-t Only Total blocks types in ibdata!              
-d Blocks types detail  in ibdata!                 
***************************************************
FILE SIZE IS : 98304
current read blocks is : 0 --This Block is file space header blocks!
current read blocks is : 1 --This Block is insert buffer bitmap  blocks!
current read blocks is : 2 --This Block is inode blocks!
current read blocks is : 3 --This Block is data blocks( index pages)!
current read blocks is : 4 --This Block is new allocate blocks!
current read blocks is : 5 --This Block is new allocate blocks!
Total Block Status    :
Total  block                   :     6,Total size is: 0.093750 MB
Total undo block               :     0,Total size is: 0.000000 MB
Total inode block              :     1,Total size is: 0.015625 MB
Total insert buffer free blocks:     0,Total size is: 0.000000 MB
Total data(index pages) block  :     1,Total size is: 0.015625 MB
Total new allocate blocks      :     2,Total size is: 0.031250 MB
Total insert buf bitmap blocks :     1,Total size is: 0.015625 MB
Total system blocks            :     0,Total size is: 0.000000 MB
Total transaction system blocks:     0,Total size is: 0.000000 MB
Total file space header blocks :     1,Total size is: 0.015625 MB
Total extrenl disc blocks      :     0,Total size is: 0.000000 MB
Total LOB blocks               :     0,Total size is: 0.000000 MB
Total Unkown blocks            :     0,Total size is: 0.000000 MB


可以看到
current read blocks is : 3 --This Block is data blocks( index pages)!
就是實際的資料,因為我這裡只有
mysql> select * from km1;
+------+---------+
| id   | name    |
+------+---------+
|    2 | gaopeng |
|    4 | gaopeng |
|    5 | gaopeng |
|    6 | gaopeng |
|    7 | gaopeng |
|    8 | gaopeng |
+------+---------+
6 rows in set (0.04 sec)


6行資料,並且是上次測試留下了,這些資料部分是從用的DELETE的空間,當然這也就是說,你的INSERT並不一定在檔案中是順序儲存的,
因為delete的空間會被重用。


[root@hadoop1 test]# bcview km1.ibd 16 94 26|more
******************************************************************
This Tool Is Uesed For Find The Data In Binary format(Hexadecimal)
Usage:./bcview file blocksize offset cnt-bytes!                   
file: Is Your File Will To Find Data!                             
blocksize: Is N kb Block.Eg: 8 Is 8 Kb Blocksize(Oracle)!         
                         Eg: 16 Is 16 Kb Blocksize(Innodb)!       
offset:Is Every Block Offset Your Want Start!                                     
cnt-bytes:Is After Offset,How Bytes Your Want Gets!                               
Edtor QQ:22389860!                                                
Used gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)                
******************************************************************
----Current file size is :0.093750 Mb
----Current use set blockszie is 16 Kb
current block:00000000--Offset:00094--cnt bytes:26--data is:00000000ffffffff0000ffffffff000000000000000000030000
current block:00000001--Offset:00094--cnt bytes:26--data is:0000000000000000000000000000000000000000000000000000
current block:00000002--Offset:00094--cnt bytes:26--data is:00000000ffffffff0000ffffffff000005d669d200000003ffff
current block:00000003--Offset:00094--cnt bytes:26--data is:0100020041696e66696d756d0007000b000073757072656d756d
current block:00000004--Offset:00094--cnt bytes:26--data is:0000000000000000000000000000000000000000000000000000
current block:00000005--Offset:00094--cnt bytes:26--data is:0000000000000000000000000000000000000000000000000000


我們只研究資料塊current block:00000003的實際資料
current block:00000003--Offset:00094--cnt bytes:26--data is:0100020041696e66696d756d0007000b000073757072656d756d
分解一下:

0100020041696e66696d756d00 為infimum的相關資訊
07000b000073757072656d756d 為SPREMUM的相關資訊

1、info flags
4位
0X0 infimum
0X0 supremum
infimum和supremum行在我測試資料庫中為binary 0000
2、number of records owned 
4位
0X1 infimum   binary 0001  1行
0X7 supremum  binary 0111  7行
3、order
由於13位不能轉化為16進位制直接給出二進位制binary
infimum 0X0002 兩位元組0000 0000 0000 0010
supermum 0X000b兩位元組0000 0000 0000 1011 
binary 0000 0000 0000 0 infimum  可以看到確實infimum在這13位上為0
binary 0000 0000 0000 1 supermum 可以看到確實supermum在這13位上為1

4、record type
infimum  3位為binary 010 及10進位制的2    可以看到確實infimum恆等於2及binary  010
supermum 3位為binary 011 及10進位制的3    可以看到確實supermum恆等於3及binary 011

5、next record offset
infimum  2個位元組為 0X0041  這裡infimum指向了下一個行的指標
supermum 2個位元組為 0X0000  這裡supermum為空指標0X0000

那麼我們就要看看infimum的指標0X0041是不是指向的資料了,
0X0041 十進位制為65,這個位置是infimum header 結束位置相對偏移量及99
我們知道int型別為4BYTES而我的資料'gaopeng'為7位元組
那麼就是11位元組
同時在我們的頁資料塊,當然我這裡就一個塊當然也就是頁塊了
他的資料結構實際如下:
CLUSTER KEY FIELDS 主鍵位元組數,我這裡沒有就是ROWID,6位元組
transaction id     固定6位元組
roll pointer       固定7位元組
Non-key fields     就是資料的位元組數,我這裡就是11位元組了
那麼我們可以算出起始位置為99+65=164 檢視的位元組數為 11+6+6+7=30
注意這裡的偏移量為65很顯然,這裡不是物理的第一行,order 排序的第一行。order就是插入的順序,原來的第一行被我DELETE掉了,空間重用過了。

bcview km1.ibd 16 164 30|more
current block:00000003--Offset:00164--cnt bytes:30--data is:000001cc64260000002d0272d300000d1201108000000267616f70656e67
分解一下資料
000001cc6426   ROWID
0000002d0272   transaction id
d300000d120110 roll pointer
80000002       資料2,這裡8出現在第15位,可能為符號位
67616f70656e67 資料'gaopeng'的ascII值

可以看到沒有問題,我們找到了他的資料,由於ROW HEADER是可變的,所以這個指標指向是資料的開頭,而不包含行頭
行頭資訊需要計算offset後像前面偏移N個位元組開始,當然這內容以後再討論
關於行的格式會在以後的文章中給出,這裡重要解釋infimum和supermum,

6、"infimum\0"和"supermum"

這個沒什麼好說的就是ASCII值
696e66696d756d00="infimum\0"
73757072656d756d="supermum"

最後
這裡在做一個測試試一下 bigint UNSIGNED  型別 
首先測試bigint是否為8個位元組,同時測試符號位
mysql> create table km15(id   bigint UNSIGNED ,name varchar(20));
Query OK, 0 rows affected (0.15 sec)
mysql> insert into km15 values(10,'gaopeng');
Query OK, 1 row affected (0.02 sec)
同樣不需要主鍵
bcview km15.ibd 16 94 26|more
current block:00000003--Offset:00094--cnt bytes:26--data is:010002001c696e66696d756d0002000b000073757072656d756d
分解資料
010002001c696e66696d756d00  infimum
02000b000073757072656d756d  supermum
infimum行的偏移量001c=28
99+28=127   
CLUSTER KEY FIELDS 主鍵位元組數,我這裡沒有就是ROWID,6位元組
transaction id     固定6位元組
roll pointer       固定7位元組
Non-key fields     就是資料的位元組數,我這裡就是8(bigint)+7位元組了=15位元組
bcview km15.ibd 16 127 34|more
current block:00000003--Offset:00127--cnt bytes:34--data is:000001cc680a0000002d0e74e0000080240110000000000000000a67616f70656e67
分解資料
000001cc680a
0000002d0e74
e0000080240110
000000000000000a 實際資料10
67616f70656e67   資料'goapeng'
沒有問題bigint UNSIGNED為8位元組同時沒有了符號位當然沒有符號位儲存的資料最大也就是2^64 如果有符號當然少一位
就是-2^32到2^32 如果有C語言的基礎也就不難理解了。

總結一下:
1、infimum和supermum 是作為資料塊的行的起始和結束位置
2、infimum和supermum 固定在94-120位元組,其中94-107為infimum 相關資訊,而107到120為supremum相關資訊
3、infimum裡面offset的偏移量是一個相對偏移量,開始位置是CLUSTER KEY的開始位置,行頭的偏移量需要相對偏移量-N,這個其實MYSQL中此類行便宜量的所有都是一樣的
4、smalint int bigint 等 在記憶體儲存中是有記可尋的,他型別和C語言一致。

相關普通行的格式會隨後分析,其實可以看到有了infimum和supermum那麼BLOCK中的資料就成了一個單項的連結串列。


 














來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2065464/,如需轉載,請註明出處,否則將追究法律責任。

相關文章