天天看點

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

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

接上一篇 

http://blog.itpub.net/7728585/viewspace-2063921/

所用到的工具是自己寫的mysqlblock和bcview,

我放到了百度雲盤

http://pan.baidu.com/s/1num76RJ

供大家下載下傳和使用

接下來就是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固定資訊

order                   13bits

"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

可以看到

就是實際的資料,因為我這裡隻有

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的實際資料

分解一下:

0100020041696e66696d756d00 為infimum的相關資訊

07000b000073757072656d756d 為SPREMUM的相關資訊

4位

0X0 infimum

0X0 supremum

infimum和supremum行在我測試資料庫中為binary 0000

0X1 infimum   binary 0001  1行

0X7 supremum  binary 0111  7行

由于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

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   

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中的資料就成了一個單項的連結清單。

繼續閱讀