<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                在上一篇里,bingxi和alex聊了關于innodb的頁編號。在本篇,bingxi和alex會討論下簇描述結構。所謂的簇描述結構,對應的英文描述是extent,表達的意思是一些連續的頁。 對應的文件為: D:/mysql-5.1.7-beta/storage/innobase/fsp/ fsp0fsp.c D:/mysql-5.1.7-beta/storage/innobase/include/ fsp0fsp.h ## 1)簇的定義 Bingxi:“alex,在共享存儲空間的情況,多個innodb表存儲在同一個表空間里面。對單個表而言,存儲并不一定是連續的。在上一篇里面提到這樣的一個例子: a)創建表1,并插入數據 b)創建表2,并插入數據 c)表1插入數據 d)表2插入數據 如果我們每次分配一個頁,就會存儲得很凌亂。可能第n頁屬于t1,n+1頁屬于t2,n+3頁屬于t1,n+4頁屬于t2,…… 這樣就會降低io的讀寫性能,因此我們可以看到在mysql中有簇的概念,這里的簇也就是指extent。簇是連續的頁,數量是64頁。那么我問下alex,假設T1表新分配了一個簇,某些頁用完了,如何標識? ” Alex:“bingxi,我也存在這個疑惑。我們用過代碼來看這個問題吧。代碼如下: ~~~ /*????????????????? EXTENT DESCRIPTOR ???????????????????? ================= File extent descriptor data structure: contains bits to tell which pages in the extent are free and which contain old tuple version to clean. */ /*-------------------------------------*/ #define??? XDES_ID???????????????????? 0???? /* The identifier of the segment ?????????????????????????????????? to which this extent belongs */ #define XDES_FLST_NODE??????? 8???? /* The list node data structure ?????????????????????????????????? for the descriptors */ #define??? XDES_STATE????????????? (FLST_NODE_SIZE + 8) ?????????????????????????????????? /* contains state information ?????????????????????????????????? of the extent */ #define??? XDES_BITMAP??????????? (FLST_NODE_SIZE + 12) ?????????????????????????????????? /* Descriptor bitmap of the pages ?????????????????????????????????? in the extent */ ~~~ 定義里面的數字是偏移量,我們來畫個圖看下。 ![](https://box.kancloud.cn/2016-07-22_5791c9c388cf6.gif) 從上面我們可以知道: XDES_ID? ?????????//0 XDES_FLST_NODE ?//8 XDES_STATE ???????//20 XDES_BITMAP ?????//24 這些內容中,我們會產生兩個疑問:1)16個字節描述64個頁的使用狀態,怎么描述?如果只是描述該頁是否使用,1個bit位就夠了,也就是64個bit位,即8個字節。而實際使用了16個字節,那么是不是可以認為是兩個bit位來描述一個頁的使用情況。2)每個簇使用40個字節,這些內容存儲在什么地方? Bingxi,你來看看。我們在本篇中,先解決第一個問題,第二個問題留到下一篇。 ” Bingxi:“第一個問題,可以理解。 ~~~ //每個頁需要兩個bit位來描述 #define??? XDES_BITS_PER_PAGE????? 2???? /* How many bits are there per page */ //這兩個bit位中,第一個bit位標識該頁是否在使用 #define??? XDES_FREE_BIT???????? 0???? /* Index of the bit which tells if ?????????????????????????????????? the page is free */ //第二個標識位目前沒有使用 #define??? XDES_CLEAN_BIT???????????? 1???? /* NOTE: currently not used! ?????????????????????????????????? Index of the bit which tells if ?????????????????????????????????? there are old versions of tuples ?????????????????????????????????? on the page */ ~~~ 每個頁使用兩個位,那么64個頁使用的就是16個字節。我們看一下簇的初始化代碼: ~~~ /************************************************************************** Inits an extent descriptor to the free and clean state. */ UNIV_INLINE void xdes_init( /*======*/ ?????? xdes_t*?? descr,????? /* in: descriptor */ ?????? mtr_t*???? mtr)/* in: mtr */ { ?????? ulinti; ?????? ut_ad(descr && mtr); ?????? ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), ???????????????????????????????????????????????? MTR_MEMO_PAGE_X_FIX)); ?????? ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0); //其中XDES_BITMAP的值為24 // XDES_SIZE的大小為40 //也就是簇描述結構中24字節開始的16個字節全部設置為1 ?????? for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) { ????????????? mlog_write_ulint(descr + i, 0xFFFFFFFFUL, MLOG_4BYTES, mtr); ?????? } ??? //設置簇的使用狀態為空閑簇 ?????? xdes_set_state(descr, XDES_FREE, mtr); }???? ~~~ 我們接著看xdes_set_state的實現: ~~~ /************************************************************************** Sets the state of an xdes. */ UNIV_INLINE void xdes_set_state( /*===========*/ ?????? xdes_t*?? descr,????? /* in: descriptor */ ?????? ulintstate,?????? /* in: state to set */ ?????? mtr_t*???? mtr)/* in: mtr handle */ { ?????? ut_ad(descr && mtr); ?????? ut_ad(state >= XDES_FREE); ?????? ut_ad(state <= XDES_FSEG); ?????? ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), ???????????????????????????????????????????????? MTR_MEMO_PAGE_X_FIX)); ??? // descr是該簇的起始指針,相對該指針XDES_STATE的開始4個字節填寫status的值 ?????? mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr); } ~~~ 同樣的,獲取狀態也是類似的。我們接著看下xdes_get_n_used函數,該函數表述該簇的頁已經使用了多少。 ~~~ /************************************************************************** Returns the number of used pages in a descriptor. */ UNIV_INLINE ulint xdes_get_n_used( /*============*/ ???????????????????? /* out: number of pages used */ ?????? xdes_t*?? descr,????? /* in: descriptor */ ?????? mtr_t*???? mtr)/* in: mtr */ { ?????? ulinti; ?????? ulintcount????? = 0; ?????? ut_ad(descr && mtr); ?????? ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), MTR_MEMO_PAGE_X_FIX)); //對該簇的每一頁調用函數xdes_get_bit // xdes_get_bit函數返回對應頁的是否使用位 //我們從初始化函數中知道,1表示使用,0表示未使用 //因為如果函數返回的值是false,則表示該頁已經使用了,將count加1 ?????? for (i = 0; i < FSP_EXTENT_SIZE; i++) { ????????????? if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) { ???????????????????? count++; ?????? ?????? } ?????? } ?????? return(count);??????? }???? ~~~ 如果所有的頁都使用完,那么就表示該頁已經使用滿。 ~~~ /************************************************************************** Returns true if extent contains no free pages. */ UNIV_INLINE ibool xdes_is_full( /*=========*/ ???????????????????? /* out: TRUE if full */ ?????? xdes_t*?? descr,????? /* in: descriptor */ ?????? mtr_t*???? mtr)/* in: mtr */ { ??? //如果該簇使用的頁等于64(FSP_EXTENT_SIZE),也就是表示該簇已經滿了 ?????? if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) { ????????????? return(TRUE); ?????? } ?????? return(FALSE); } ~~~ 其它的函數類似,這里就不一一列舉。作為重點,我們再看一下xdes_set_bit函數。 ~~~ /************************************************************************** Sets a descriptor bit of a page. */ UNIV_INLINE void xdes_set_bit( /*=========*/ ?????? xdes_t*?? descr,????? /* in: descriptor */ ?????? ulintbit,?? /* in: XDES_FREE_BIT or XDES_CLEAN_BIT */ ?????? ulintoffset,???? /* in: page offset within extent: ???????????????????? 0 ... FSP_EXTENT_SIZE - 1 */ ?????? ibool?????? val,? /* in: bit value */ ?????? mtr_t*???? mtr)/* in: mtr */ { ?????? ulintindex; ?????? ulintbyte_index; ?????? ulintbit_index; ?????? ulintdescr_byte; ?????? ?????? ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), ???????????????????????????????????????????????? MTR_MEMO_PAGE_X_FIX)); ?????? ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT)); ?????? ut_ad(offset < FSP_EXTENT_SIZE); //假設offset的值為n // XDES_BITS_PER_PAGE為2 //index也就是相對于XDES_BITMAP的偏移bit位 ?????? index = bit + XDES_BITS_PER_PAGE * offset; //index/8對應的是相對于XDES_BITMAP的偏移字節 ?????? byte_index = index / 8; ?????? //表示所在的位,這里面要重點關注 //字節是從低字節編碼的,比如n對應的bit_index是0,實際上表示的是第0位,而不是第7位。即使xxxxxxxy中的y對應的位。 //假設bit_index為6,實際對應的是xyxxxxxx中的y對應的位。 bit_index = index % 8; ??? //獲得對應的字節 ?????? descr_byte = mtr_read_ulint(descr + XDES_BITMAP + byte_index, ???????????????????????????????????????????????? MLOG_1BYTE, mtr); ?? ?//設置對應的bit位 descr_byte = ut_bit_set_nth(descr_byte, bit_index, val); ??? //重寫入 ?????? mlog_write_ulint(descr + XDES_BITMAP + byte_index, descr_byte, ???????????????????????????????????????????????? MLOG_1BYTE, mtr); }???? ~~~ 這樣,我們對應簇的bit位進行設置,標識對應的頁的使用情況。還有一些其他的函數,建議直接看代碼。 ” Alex:“ok,今天就到這里吧。” Bingxi:“ok”
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看