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的varchar儲存原理:InnoDB記錄儲存結構MySql
- 隨筆:MySQL中'' ' ' NULL在Innodb儲存的區別MySqlNull
- MySQL InnoDB 儲存引擎探祕MySql儲存引擎
- MySQL中InnoDB儲存引擎的實現和執行原理MySql儲存引擎
- MySQL儲存引擎:MyISAM和InnoDB的區別MySql儲存引擎
- MySQL資料庫InnoDB儲存引擎中的鎖機制GVMySql資料庫儲存引擎
- MySQL儲存引擎--MyISAM與InnoDB區別MySql儲存引擎
- 《MySQL 效能優化》之 InnoDB 儲存引擎MySql優化儲存引擎
- [Mysql技術內幕]Innodb儲存引擎MySql儲存引擎
- MySQL InnoDB儲存引擎體系結構MySql儲存引擎
- MySQL-07.InnoDB資料儲存結構MySql
- MySQL提升筆記(4)InnoDB儲存結構MySql筆記
- 談談MySQL InnoDB儲存引擎事務的ACID特性MySql儲存引擎
- 軟體定義儲存助力數字中國建設:智慧高效又經濟的資料儲存方式
- 十八、Mysql儲存引擎並不只有MyISAM、InnoDB——精髓MySql儲存引擎
- MySQL高階10-InnoDB引擎儲存架構MySql架構
- 每日分享-MySQL-2019-08-05-【InnoDB 儲存引擎】MySql儲存引擎
- 總結MySQL儲存引擎MyISAM與InnoDB區別MySql儲存引擎
- MySQL儲存引擎簡介及MyISAM和InnoDB的區別MySql儲存引擎
- mysql儲存引擎InnoDB詳解,從底層看清InnoDB資料結構MySql儲存引擎資料結構
- 服務端指南 資料儲存篇 | MySQL(02) 儲存引擎的 InnoDB 與 MyISAM 之爭服務端MySql儲存引擎
- MySQLInnoDB儲存引擎(一):精談innodb的儲存結構MySql儲存引擎
- MySQL三種InnoDB、MyISAM和MEMORY儲存引擎對比MySql儲存引擎
- MySQL中陣列的儲存MySql陣列
- 《MySQL 基礎篇》十二:InnoDB 儲存引擎的資料結構MySql儲存引擎資料結構
- mysql儲存過程的引數MySql儲存過程
- InnoDB儲存引擎簡介儲存引擎
- 變數的儲存方式和生存期變數
- MySQL兩種儲存引擎: MyISAM和InnoDB 簡單總結MySql儲存引擎
- MySQL原理 - InnoDB引擎 - 行記錄儲存 - Off-page 列MySql
- MySQL InnoDB儲存引擎更新Cardinality統計資訊的策略介紹MySql儲存引擎
- MySQL常見的兩種儲存引擎:MyISAM與InnoDB的愛恨情仇MySql儲存引擎
- innodb儲存引擎鎖的實現(一)儲存引擎
- 14.1 InnoDB 儲存引擎介紹儲存引擎
- InnoDB記錄儲存結構
- Innodb 下null '' ' '的儲存表現的不同Null
- MySQL之儲存引擎InnoDB和MyISAM的區別及底層詳解MySql儲存引擎