MySQL:Innodb中數字的儲存方式
一、問題來源
如果我們檢視show egnine innodb檢視鎖記錄的時候往往會看到Innodb的數字使用類似
80000001的形式顯示如下:
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 1; hex 31; asc 1;;
1: len 1; hex 31; asc 1;;
2: len 1; hex 80; asc ;;
3: len 8; hex 8000000000000001; asc ;;
這裡是一個有符號的bigint的顯示。本文就來說一下這個值是這麼計算出來的。本文以4位元組的int為例。
二、原始碼部分
關於轉換的部分主要集中在函式row_mysql_store_col_in_innobase_format中,我們來看一下數字的轉換程式碼如下:
if (type == DATA_INT) {
/* Store integer data in Innobase in a big-endian format,
sign bit negated if the data is a signed integer. In MySQL,
integers are stored in a little-endian format. */
byte* p = buf + col_len; //p指標指向buf的 最高地址, 反向獲取資料 得到大端 buffer是
for (;;) {
p--;
*p = *mysql_data; //轉大端
if (p == buf) { //如果儲存完成
break;
}
mysql_data++;
}
if (!(dtype->prtype & DATA_UNSIGNED)) {//如果為有符號型別
*buf ^= 128;
}
ptr = buf; //PTR指向 buffer低地址
buf += col_len;//buf指向 buffer的高地址
}
...
dfield_set_data(dfield, ptr, col_len); //存入dtuple中,裡面很簡單就是取void* 存進去進行了。
這裡的關鍵部分就是對於有*buf ^= 128;這部分,實際上就是轉換為大端後的最低位做一個異或操作。
最終操作為函式page_cur_tuple_insert會將這個dtuple插入到實際的資料檔案其中有一個函式為rec_convert_dtuple_to_rec_comp,會獲得最終的物理記錄,其中的程式碼memcpy(end, dfield_get_data(field), len);可以看到實際存入物理記錄的就是這裡的轉換後的值。
三、例項解析
1. 有符號
正數:以數字5為例子,其4位元組的表示方法為0x05 0x00 0x00 0x00,這裡還是小端形式為MySQL層傳入的值。Innodb轉換方式如下:
- 從高地址開始取,轉換為大端形式,轉換後為
0x00 0x00 0x00 0x05 - 如果為有符號型別轉換為大端後的最低位做一個異或操,轉換為
0x80 0x00 0x00 0x05
負數:以數字-5為例子,其4位元組的表示方法為0xfb 0xff 0xff 0xff(補碼),這裡還是小端形式為MySQL層傳入的值。Innodb轉換方式如下:
- 從高地址開始取,轉換為大端,轉換後為
0xff 0xff 0xff 0xfb - 如果為有符號型別轉換為大端後的最低位做一個異或操,轉換為
0x7f 0xff 0xff 0xfb
2、無符號
這個比較簡單,直接原始值大端輸出即可,不做最後的異或操作。
四、測試
我們為了測試就建立一個表如下:
create table testint(id int primary key);
insert into testint values(5),(-5);
然後使用innblock和bcview檢視二進位制檔案中儲存的方式。
第一行記錄為:
轉換如下:
80000005 實際記錄5
000000014224 trx id
bd000000230110 roll ptr
第二行記錄為:
7ffffffb 實際記錄-5
000000014224 trx id
bd00000023011d roll ptr
我們可以發現我們的分析是正確,確實物理檔案中也是這樣儲存的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2707568/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL InnoDB儲存引擎MySql儲存引擎
- 隨筆:MySQL中'' ' ' NULL在Innodb儲存的區別MySqlNull
- MySQL Innodb 儲存結構 & 儲存Null值 解析MySqlNull
- MySQL的varchar儲存原理:InnoDB記錄儲存結構MySql
- MySQL InnoDB 儲存引擎探祕MySql儲存引擎
- MySQL InnoDB的儲存結構總結MySql
- MySQL中InnoDB儲存引擎的實現和執行原理MySql儲存引擎
- MySQL資料庫InnoDB儲存引擎中的鎖機制GVMySql資料庫儲存引擎
- MySQL儲存引擎:MyISAM和InnoDB的區別MySql儲存引擎
- MySQL儲存引擎MyISAM與InnoDB的優劣MySql儲存引擎
- Mysql innodb儲存引擎的效能最佳化MySql儲存引擎
- Mysql技術內幕InnoDB儲存引擎讀書筆記--《二》InnoDB儲存引擎MySql儲存引擎筆記
- InnoDB儲存引擎——Master Thread工作方式儲存引擎ASTthread
- [Mysql技術內幕]Innodb儲存引擎MySql儲存引擎
- MySQL InnoDB儲存引擎體系結構MySql儲存引擎
- 《MySQL 效能優化》之 InnoDB 儲存引擎MySql優化儲存引擎
- MySQL儲存引擎--MyISAM與InnoDB區別MySql儲存引擎
- MySQL技術內幕:InnoDB儲存引擎MySql儲存引擎
- 儲存過程中巢狀儲存過程的變數執行方式儲存過程巢狀變數
- Innodb儲存引擎儲存引擎
- MyISAM 儲存引擎,Innodb 儲存引擎儲存引擎
- MySQL提升筆記(4)InnoDB儲存結構MySql筆記
- Mysql核心:INNODB儲存引擎--《十一》Insert BufferMySql儲存引擎
- MySQL核心InnoDB儲存引擎(卷1)筆記MySql儲存引擎筆記
- InnoDB儲存引擎——表儲存引擎
- 總結MySQL儲存引擎MyISAM與InnoDB區別MySql儲存引擎
- 十八、Mysql儲存引擎並不只有MyISAM、InnoDB——精髓MySql儲存引擎
- MySQL高階10-InnoDB引擎儲存架構MySql架構
- MySQL 5.6 InnoDB儲存引擎體系結構圖MySql儲存引擎
- 《MySQL技術內幕:InnoDB儲存引擎》連載MySql儲存引擎
- MySQL儲存引擎簡介及MyISAM和InnoDB的區別MySql儲存引擎
- MYSQL innodb buffer 狀態資料的儲存和載入MySql
- 談談MySQL InnoDB儲存引擎事務的ACID特性MySql儲存引擎
- 【轉】Mysql兩種儲存引擎的異同【MyISAM和InnoDB】MySql儲存引擎
- Mysql更換MyISAM儲存引擎為Innodb的操作記錄MySql儲存引擎
- MySQL資料庫MyISAM儲存引擎轉為Innodb的方法MySql資料庫儲存引擎
- MySQL中陣列的儲存MySql陣列
- 軟體定義儲存助力數字中國建設:智慧高效又經濟的資料儲存方式