精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深度解析Innodb記錄格式源碼

數據庫 MySQL 數據庫運維
筆者很長時間又不寫東西了,之前已經看過了innodb格式,但現在想研究一下其它方面的東西,突然發現這個又忘了,索性再看看把它寫下來。

 可以通過一個最普遍的插入操作來跟蹤Innodb的記錄格式,因為在插入時,系統得到的是公共的mysql記錄格式record,現在它沒有涉及到任何的存儲引擎,那么這里不管當前這個表對應的存儲引擎是什么,記錄格式是一樣的,對于插入,mysql函數對應的是ha_write_row,具體到Innodb存儲引擎,實際調用的函數是ha_innobase::write_row函數,那么在這里,Innodb首先會將接收到的record記錄轉換為它自己的一個元組tuple,這其實是與record對應的innodb的表示方式,它是一個內存的記錄,邏輯的記錄,那么在系統將其真正的寫入到頁面之前,這條記錄的存在方式都是這個tuple,那么下面主要是從源碼的角度研究Innodb是如何將一個tuple轉換為它的物理的存儲記錄的,主要研究代碼的實現邏輯及記錄的格式。

這里只介紹格式為Compact類型的記錄格式。

實現在某一個頁面插入一個元組(一條記錄)操作的函數是page_cur_tuple_insert,它的參數就是一個dtuple_t*類型的tuple,在這里,它首先要分配一片空間來存儲將要轉換過來的物理記錄,所以這里需要先計算空間的大小,計算方法如下:

1. 首先每條記錄都要包括下面2個部分:REC_N_NEW_EXTRA_BYTES + UT_BITS_IN_BYTES(n_null),前面表示的是這種格式的固定長度的extra部分,這部分用來存儲什么內容后面會給出,后面表示的是所有字段中哪些字段的值是null,當然這里只存儲那些nullable屬于的字段,如果創建表的時候指定是not null的話,這里就不會被存儲,那么這里是用一個位來表示一個字段的null屬性。那么上面這部分被系統代碼命名為extra_size變量值。

2. 統計每一個列中數據的長度,在統計這個信息的時候,又有多種情況,主要分定長字段和變長字段,對于定長字段,它的長度直接就是數據類型的長度,比如int類型的那就是4個字節,rowid列就是6個字節等,沒有其它附加長度。對于變長字段而言,除了數據內容本身的長度外,還需要計算其數據長度的存儲空間,如果字段的字義長度大于255個字節,或者字段的數據類型為BLOB的,那么需要用2個字節來存儲這個字段的長度;如果定義長度小于128個字節,或者小于256個字節,但類型不是BLOB類型的,那么這個字段的數據長度用一個字節來存儲,除上面2種情況之外,都用2個字節來存儲。那么在這一部分中,用來存儲變長字段數據的長度的空間的長度也是被Innodb計算為extra_size的。

所以現在可以知道,一個innodb的記錄包括2個部分,一部分是extra_size,另一部分是數據內容,那么這2部分的總長度就是上面計算出來的結果,這里把它定義為record_size。

接下來,申請空間,進行元組到記錄的轉換工作。

轉換函數為rec_convert_dtuple_to_rec_new,參數有申請好的記錄空間buf,元組和索引的內存結構。

首先這里有一個操作是rec = buf + extra_size,變量rec表示的是數據內容的存儲開始位置。extra_size就是上面計算出來的2個數據部分。

那么真正執行轉換的是接下來調用的rec_convert_dtuple_to_rec_comp函數,下面是其原型:

  1. void 
  2.   
  3.  rec_convert_dtuple_to_rec_comp( 
  4.   
  5.  /*===========================*/ 
  6.   
  7.           rec_t*                          rec,   /*!< in: origin of record */ 
  8.   
  9.           ulint                    extra,        /*!< in: number of bytes to 
  10.   
  11.                                                 reserve between the record 
  12.   
  13.                                                 header and the data payload 
  14.   
  15.                                                 (normally REC_N_NEW_EXTRA_BYTES) */ 
  16.   
  17.           const dict_index_t*  index,        /*!< in: record descriptor */ 
  18.   
  19.           ulint                    status,       /*!< in: status bits of the record */ 
  20.   
  21.           const dfield_t*          fields,        /*!< in: array of data fields */ 
  22.   
  23.           ulint                    n_fields)/*!< in: number of data fields */ 

 

rec表示的是剛才上面計算出來的rec變量,extra表示的是固定長度的REC_N_NEW_EXTRA_BYTES。

 

  1. end = rec; 
  2.   
  3.           nulls = rec - (extra + 1); 
  4.   
  5.           n_null = index->n_nullable; 
  6.   
  7.           lens = nulls - UT_BITS_IN_BYTES(n_null); 
  8.   
  9.           /* clear the SQL-null flags */ 
  10.   
  11.           memset(lens + 1, 0, nulls - lens); 

在這里,這段代碼一下子很難看明白,那么首先這里畫一下記錄存儲格式:

 

 

         |---------------------extra_size-----------------------------------------|---------fields_data------------|

         |--columns_lens---|---null lens----|------fixed_extrasize(5)------|--col1---|---col2---|---col2----|

那么語句nulls = rec - (extra + 1);得到的結果是什么呢?想干什么?因為extra表示的是REC_N_NEW_EXTRA_BYTES,固定長度的fixed_extrasize,rec表示的是圖中col1的開始位置,那么現在可以知道這條語句的結果就是使得nulls指向了前面nulllens的后一個字節的開始位置。那現在我們知道nulls是一個或者多個字節,用來存儲每一個nullable字段的空標志的,那現在為什么要指向這個數組的后一個字節的開始位置呢?一下子很難想明白,不過從后面的代碼中可以知道,寫入nulls是從后面向前面寫的,所以這也理解了為什么指向了后面一個字節的位置了。

那接下來的一個語句lens = nulls - UT_BITS_IN_BYTES(n_null);道理也是一樣的,因為columns_lens正好是在nulllens的前面,那么如果向前跳過null標志的所有空間,則指向的位置lens就是columns_lens的后面一個字節的位置了。在寫入值的時候也是從后面向前面寫。

那最后一個語句memset(lens + 1, 0, nulls - lens);表示的意思就很明白了,因為lens指向的是columns_lens的最后一個字節的開始位置,那么加1就指向了nulls空間的開始位置,nulls – lens表示的是nulls空間的長度。這里是將nulls空間清零。

上面有兩個部分都是從后面向前面填寫數據,那是不是擔心在寫入的時候會不會向前面越界呢?其實是不會的,因為這些都是在前面計算好的,extrasize已經是固定的,包括了nulls和columns_lens的長度的。

上面算是初始化工作,下面就是根據每一個字段來填寫record記錄了,下面一段代碼是處理null信息的,對于每一個字段,都會做下面的處理:

 

  1. if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { 
  2.                 /* nullable field */ 
  3.                 ut_ad(n_null--); 
  4.                 if (UNIV_UNLIKELY(!(byte) null_mask)) { 
  5.                           nulls--; 
  6.                           null_mask = 1; 
  7.                 } 
  8.                 ut_ad(*nulls < null_mask); 
  9.                 if (dfield_is_null(field)) { 
  10.                        *nulls |= null_mask; 
  11.                        null_mask <<= 1; 
  12.                        continue
  13.               } 
  14.               null_mask <<= 1; 
  15.      } 

從第一行可以看出,要處理這個的條件首先必須是沒有定義not null屬性,所以nulls空間只存儲這些字段的信息。

 

第4行表示的是如果(byte) null_mask)為0時,nulls向前退一個字節,并且將null_mask恢復為1的初值,因為這個值初始值就是1的,可以猜到,如果這個條件滿足了,則說明已經寫入了8個nullable列了,那么需要移向前一個字節繼續寫null信息了,但發現null_mask是int類型的,而nulls是一個字節一個字節的填的,不匹配啊,不過仔細看,判斷條件是(byte) null_mask),所以只要寫入8個之后,這個值就為0了。因為對于每一個字段,都是執行null_mask向左移1個位的,所以移8次之后,低8位就都是0了。

第9行表示的是如果這個列的數據就是null值,那么需要將這個null反映到nulls數組中去,因為null_mask當前的值(其實是1的位置)其實表示的是當前nulls這個字節中正在處理的字段的對應關系,也就是說,如果當前的字段的值為null,那么像第10行所示的,將null_mask或到nulls字節上去,如果不為null,就不管,對應的位的值為0。

所以從這里可以看出,整個nulls空間中的位圖是以從后面向前面的順序來表示所有nullable列的null信息的。

 

  1. if (fixed_len) { 
  2.        } else if (dfield_is_ext(field)) { 
  3.                 *lens-- = (byte) (len >> 8) | 0xc0; 
  4.                 *lens-- = (byte) len; 
  5.        } else { 
  6.                 if (len < 128 || (dtype_get_len(type) < 256 && dtype_get_mtype(type) != DATA_BLOB)) { 
  7.                           *lens-- = (byte) len; 
  8.                 } else { 
  9.                           *lens-- = (byte) (len >> 8) | 0x80; 
  10.                        *lens-- = (byte) len; 
  11.               } 
  12.      } 
  13.      memcpy(end, dfield_get_data(field), len); 
  14.      end += len; 

從第一行可以看出,對于定長數據,只需要將其數據寫入到記錄里面即可,主要處理的是變長數據,第2行表示的是如果長度大于256個字節,或者數據類型為BLOB,則用兩個字節來存儲其長度,低字節存儲(len >> 8) | 0xc0,高字節存儲(byte) len(被截斷)。其它可以直接看出來。

 

到13行,是直接將數據拷到數據存儲空間,用end來表示,存儲完一個字段接著下一個字段,是按照索引定義的順序存儲的。

到這里,一條記錄的邏輯到物理的轉換就完成了,從中也知道了Innodb是如何實現其物理記錄的存儲的。

總結:看innodb的代碼,可以說它的代碼非常優美,非常精練的,所以有些地方很難一下子看懂,需要揣測,體會才能深入的理解。同時有很多地方是直接硬編碼的,這樣導致更加難理解,最好的方式是通過宏將其命名,有助于理解。

原文鏈接:http://www.cnblogs.com/bamboos/archive/2013/03/04/2943160.html

【編輯推薦】

  1. 適合初學者的MySQL學習筆記之庫操作示例
  2. 適合初學者的MySQL學習筆記之表操作示例
  3. 適合初學者的MySQL學習筆記之MySQL管理心得
  4. 適合初學者的MySQL學習筆記之MySQL查詢示例
  5. 適合初學者的MySQL學習筆記之管理員常用操作總結

責任編輯:彭凡 來源: 博客園
相關推薦

2016-12-15 09:44:31

框架Caffe源碼

2022-12-07 08:02:43

Spring流程IOC

2025-09-24 18:39:45

2025-09-26 02:00:55

JDKCPU內存

2024-09-11 09:25:03

Tomcat組件PREP

2022-08-17 07:52:31

Spring循環依賴單例池

2023-05-08 08:11:49

@Component使用場景時序圖

2021-05-26 11:30:24

Java線程池代碼

2024-01-11 12:14:31

Async線程池任務

2025-03-14 12:30:00

Redis RDBRedis數據庫

2025-06-04 02:10:35

`@scope`CSS源碼

2025-11-14 00:00:15

2021-07-03 08:51:30

源碼Netty選擇器

2022-09-27 18:56:28

ArrayList數組源代碼

2025-06-04 08:30:00

seata分布式事務開發

2023-10-10 11:02:00

LSM Tree數據庫

2023-03-27 08:12:40

源碼場景案例

2023-03-06 11:13:20

Spring注解加載

2013-12-09 10:34:12

2023-03-13 08:12:25

@DependsOn源碼場景
點贊
收藏

51CTO技術棧公眾號

亚洲色图在线视频| 麻豆久久一区二区| 精品亚洲一区二区三区在线播放| 动漫av网站免费观看| 成年人免费在线视频| 精品一区二区三区在线播放| 午夜精品久久久久久久久久久久| 波多野结衣av在线观看| 精品一区二区三区免费看| 黑人与娇小精品av专区| 在线视频91| 四虎电影院在线观看| 久久aⅴ国产欧美74aaa| 9.1国产丝袜在线观看 | 亚洲国产精品传媒在线观看| 91黄在线观看| 波多野结衣视频在线看| 国内久久视频| 色先锋资源久久综合5566| 亚洲少妇18p| www 久久久| 在线一区二区三区四区| 草b视频在线观看| 黄色成人影院| 国产日产亚洲精品系列| 国产精品国产精品国产专区蜜臀ah | 奇门遁甲1982国语版免费观看高清| 久久精品在线观看视频| 自拍欧美一区| 亚洲加勒比久久88色综合| av噜噜在线观看| 欧美色999| 婷婷夜色潮精品综合在线| ijzzijzzij亚洲大全| 国产视频福利在线| 91欧美一区二区| 精品国产一区二区三区免费| 精品国精品国产自在久不卡| 久久99精品国产麻豆婷婷 | 少妇一级淫片日本| 国产美女一区| 欧美性视频精品| 国产一区二区三区影院| 精品不卡视频| 欧美高清在线视频观看不卡| 色欲一区二区三区精品a片| 青草国产精品| 色天天综合狠狠色| 在线观看天堂av| 日韩精品永久网址| 在线电影av不卡网址| 久久久久久久毛片| 欧美日中文字幕| 国产一区二区三区在线免费观看| av在线网站观看| 国产videos久久| 国产亚洲精品久久久| 亚洲黄色小说视频| 日韩精品久久| 久久九九有精品国产23| 26uuu成人网| 欧美另类亚洲| 久久久久国产精品一区| 黄色小视频在线免费看| 亚洲二区在线| 热re91久久精品国99热蜜臀| 国产一区二区视频网站| 日本不卡在线视频| 国产色婷婷国产综合在线理论片a| 亚洲综合精品国产一区二区三区| 九色|91porny| 鬼打鬼之黄金道士1992林正英| 性一交一乱一色一视频麻豆| proumb性欧美在线观看| 你懂的网址一区二区三区| 国产经典自拍视频在线观看| 国产精品免费视频一区| 久久av高潮av| 天堂资源在线| 欧美日韩精品免费观看视频| 日韩欧美中文视频| 偷拍视屏一区| 色偷偷av一区二区三区乱| 欧美日韩免费一区二区| 国产精品资源| 国产在线观看一区二区三区| 亚洲国产精品国自产拍久久| 久久蜜桃香蕉精品一区二区三区| 性欧美大战久久久久久久免费观看| 久草中文在线观看| 欧美日韩国产精品专区| 污污动漫在线观看| 国产精品白浆| 北条麻妃一区二区三区中文字幕| 免费在线观看黄色av| 可以免费看不卡的av网站| 91久久精品在线| 日本在线视频1区| 亚洲欧美日韩中文播放| 久久久久久久久久福利| 欧美a在线观看| 亚洲欧美制服中文字幕| 成人免费视频网站入口::| 蜜桃伊人久久| 91啪国产在线| 国产免费av在线| 亚洲尤物视频在线| 国产 porn| 国产精品极品| 精品精品国产国产自在线| 日韩av女优在线观看| 久久99精品久久久久久国产越南| 久久久久欧美| 久久五月精品中文字幕| 欧美色图12p| 不卡一区二区在线观看| 欧美日韩午夜| 成人国产在线视频| 免费av在线电影| 亚洲v日本v欧美v久久精品| 久久久久久久久久一区二区| 亚洲区小说区图片区qvod| 欧美日韩国产123| 97成人在线观看| 国产欧美日韩综合| 日本精品免费在线观看| 91精品国产乱码久久久竹菊| 色999日韩欧美国产| 国产熟妇一区二区三区四区| 99精品视频一区| 日韩一级特黄毛片| 国产精品**亚洲精品| 中国日韩欧美久久久久久久久| 久草国产精品视频| 成人免费不卡视频| 久久男人资源站| 国产免费av国片精品草莓男男| 日韩中文字幕国产| 瑟瑟视频在线免费观看| 久久久久国产精品厨房| 欧美日韩激情视频在线观看| 九九热hot精品视频在线播放| 九九精品视频在线| 午夜精品久久久久久久第一页按摩| 中文字幕在线不卡一区二区三区| 免费看污污网站| 欧美一级精品| 国产精品久久久久久久久久久不卡| 天堂av在线资源| 欧美午夜片在线免费观看| 亚洲欧美色图视频| 宅男噜噜噜66国产日韩在线观看| 国产一区精品视频| 欧美极品videos大乳护士| 亚洲精品久久久久久久久久久| 日韩免费一二三区| 91在线丨porny丨国产| www国产精品内射老熟女| 理论片一区二区在线| 欧美一区二三区| 国产理论电影在线观看| 精品1区2区3区| 欧美成人777| 高清免费成人av| 日韩欧美一区二| 欧美猛男同性videos| 国产精品久久久久久久久男 | 欧美人与动xxxxz0oz| 4p变态网欧美系列| av在线电影观看| 51精品秘密在线观看| 免费三片在线播放| 972aa.com艺术欧美| 国产精品动漫网站| 999国产精品999久久久久久| 99精品国产高清在线观看| 啊啊啊久久久| 亚洲一级片在线看| 国产福利免费视频| 欧美日韩中文字幕综合视频| 日本高清黄色片| 国产精品一区二区果冻传媒| 六月婷婷在线视频| 日韩欧美电影| 国产精品久久一区二区三区| 裤袜国产欧美精品一区| 久久久99久久精品女同性| 日韩一卡二卡在线| 欧美视频一区在线| 国产大片中文字幕| 中文字幕乱码一区二区免费| www.四虎在线| 美女mm1313爽爽久久久蜜臀| 欧美黄网在线观看| 黑人操亚洲人| 国产精品二区在线| av在线播放一区| 97久久精品国产| 免费黄色在线看| 亚洲另类激情图| 午夜免费福利视频| 欧美综合天天夜夜久久| 精品小视频在线观看| 中文字幕成人av| 亚洲国产精品无码久久久久高潮| 久久国内精品视频| 日韩精品视频久久| 欧美激情aⅴ一区二区三区| 欧美在线视频一区二区三区| avtt综合网| 91精品视频一区| 欧美日韩视频免费观看| 欧美激情第一页xxx| 日本三级在线播放完整版| 精品夜色国产国偷在线| 亚洲爱情岛论坛永久| 欧美日韩国产首页在线观看| 日本午夜视频在线观看| 亚洲一区二区三区四区在线免费观看 | 色综合久久天天| 国产91av视频| 亚洲精品日韩一| 国产又色又爽又高潮免费| 91片黄在线观看| 亚洲一区二区三区黄色| 国产一区二区影院| 在线能看的av网站| 麻豆免费精品视频| 亚洲国产精品三区| 日韩二区三区在线观看| 国产免费成人在线| 国产亚洲在线| 一女被多男玩喷潮视频| 亚洲大胆av| 国产一区二区四区| 欧美欧美全黄| 久久男人资源站| 禁久久精品乱码| 草草视频在线免费观看| 亚洲香蕉网站| 国产夫妻自拍一区| 黄色av成人| 性一交一乱一伧国产女士spa| 女生裸体视频一区二区三区| www亚洲国产| 亚洲激情久久| 丰满人妻一区二区三区53号| 自由日本语亚洲人高潮| 青青草视频国产| 欧美日韩视频一区二区三区| 男女激情免费视频| 在线成人av| 国产午夜伦鲁鲁| 久久亚洲综合| 欧美午夜性生活| 麻豆国产精品视频| 在线看免费毛片| 国产精品资源在线| 国产chinese中国hdxxxx| 波多野结衣精品在线| 极品粉嫩小仙女高潮喷水久久| 91啪九色porn原创视频在线观看| x88av在线| 自拍偷拍亚洲欧美日韩| 久久中文字幕在线观看| 五月婷婷久久丁香| 在线免费观看av网址| 欧美日韩色一区| 亚洲成人777777| 日韩www在线| 91在线看黄| 久久国产精品偷| 国产调教在线| 国产精品视频久久久| 国产精品视频首页| 韩国成人av| 日韩伦理一区| 久久亚洲国产成人精品无码区| 国产亚洲福利| 黄色永久免费网站| 成熟亚洲日本毛茸茸凸凹| 男女黄床上色视频| 亚洲欧洲韩国日本视频| www.youjizz.com亚洲| 日本韩国欧美在线| 99国产在线播放| 亚洲精品丝袜日韩| yellow91字幕网在线| 欧美一级视频在线观看| 亚洲最大的免费视频网站| 国产精品一国产精品最新章节| 国产精品手机在线播放| www.99riav| 欧美aa在线视频| 国产女主播在线播放| 欧美国产激情一区二区三区蜜月| 青娱乐av在线| 欧美视频在线一区二区三区 | 亚洲午夜久久久久久久| www红色一片_亚洲成a人片在线观看_| 9.1国产丝袜在线观看| 成人影院网站ww555久久精品| 久久久99国产精品免费| 综合久久亚洲| 最新中文字幕免费视频| av在线播放成人| 男人操女人的视频网站| 欧美综合色免费| 天天在线女人的天堂视频| 欧美猛交ⅹxxx乱大交视频| 亚洲成av在线| 精品欧美一区二区精品久久| 欧美99久久| 黄大色黄女片18第一次| 久久亚洲精精品中文字幕早川悠里 | 美女网站免费观看视频| 激情综合网激情| 无码少妇一区二区| 欧美日韩一区二区在线 | 成人午夜888| 亚洲精品高清视频| 久久亚洲美女| 亚洲国产欧美视频| 午夜视频久久久久久| 精品人妻一区二区三区含羞草 | 久久99九九99精品| 欧美人与性囗牲恔配| 91黄色免费看| 天堂中文网在线| 亚洲91av视频| 激情av综合| 欧美一级视频在线播放| 国产精品12区| 国产黄色片在线免费观看| 欧美疯狂做受xxxx富婆| 亚洲欧美视频一区二区| 国产精品入口免费视频一| 国产欧美日韩一区二区三区四区| 国产精品一区二区免费在线观看| 成人国产精品视频| 99免费在线观看| 欧美精品一区二| 大黄网站在线观看| 国产精品一区二区三区免费观看| 国产精品v日韩精品v欧美精品网站| 一区二区三区四区毛片| 自拍偷拍欧美精品| 午夜精品久久久久久久爽| 欧美极品美女视频网站在线观看免费 | 国产高清一区视频| 亚洲黄色av| 亚洲精品理论片| 在线这里只有精品| 在线观看精品一区二区三区| 国产中文字幕日韩| 午夜精品电影| 国产黑丝在线观看| 色狠狠av一区二区三区| www亚洲人| 91久久久在线| 最新日韩在线| 偷拍女澡堂一区二区三区| 91国偷自产一区二区三区成为亚洲经典| 黄色电影免费在线看| 国产欧美日韩专区发布| 久久久久国产| 精品人妻一区二区免费| 疯狂做受xxxx高潮欧美日本| 国产视频网站在线| 亚洲a成v人在线观看| 亚洲激情av| 亚洲av成人无码一二三在线观看| 亚洲一区二区视频| 男男激情在线| 成人在线小视频| 91成人精品视频| 国产精久久久久| 黑丝美女久久久| 日韩黄色影院| 韩国成人一区| 丝袜亚洲精品中文字幕一区| 国产精品久久久免费看| 精品少妇一区二区三区视频免付费| 美女av在线免费看| 一级做a爰片久久| 99国产欧美另类久久久精品| 艳妇乳肉豪妇荡乳av| 久久久免费在线观看| heyzo久久| 日韩无码精品一区二区| 精品污污网站免费看| 爱看av在线入口| 亚洲视频在线观看日本a| 成人精品视频网站| 伊人网中文字幕| 668精品在线视频| 亚洲影视一区二区三区| 伊人网在线视频观看| 日韩视频免费观看高清完整版| 久久夜夜操妹子|