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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                在上一篇,bingxi和alex聊了關于簇描述結構。在本篇,bingxi和alex會討論下簇頁管理。所謂的簇頁,就是用于管理簇結構的頁。 對應的文件為: 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,我們上一篇聊了簇結構,一個簇描述結構大小為40個字節,管理64個頁。這40個字節存儲在什么地方呢?0~63頁是一個簇,那么n*64~(n+1)*64-1也需要一個簇描述結構。嗯,因此可以將第0頁用于存儲這些結構,假設存儲k個。也就是描述了64k個頁,接著第64k這個頁繼續描述接下來的64k個頁,以此類推。如圖1 ![](https://box.kancloud.cn/2016-07-22_5791c9c3a3159.gif) 從圖1中可以看到,首先是0頁管理64k個頁(也就是個k個簇),接著第64k這個頁管理后面的64k個頁,依次類推。 現在轉化為,這個k值是多少?alex,你從代碼里面看看。 ” Alex:“我們看下fsp0fsp.h中宏定義 ~~~ /* Number of pages described in a single descriptor page: currently each page description takes less than 1 byte; a descriptor page is repeated every this many file pages */ //該值描述一個簇描述頁可以描述的頁數,也就是每XDES_DESCRIBED_PER_PAGE個頁出現一個簇頁,UNIV_PAGE_SIZE的值我們可以知道是16k(也就是16384)。 #define XDES_DESCRIBED_PER_PAGE?????????? UNIV_PAGE_SIZE ~~~ 從定義中可以看出,一個簇頁可以描述16384個頁,也就是256個簇描述結構(16384/64=256)。這256個簇占用的大小為10k(256*40=10k)。而一個頁是16k,剩下不到6k的空閑是不使用的。 這里面,我們就可以知道1個簇頁可以描述的頁為16384,對應的大小為256M(16384*16K=256M)。即1個簇頁管理256M。因此,實際對應的簇頁管理見圖2: ![](https://box.kancloud.cn/2016-07-22_5791c9c3bda4a.gif) 接著就帶來一個算法,知道一個頁號n,它對應的簇頁編號是多少。如果n為0~16384-1,則對應的簇頁為0,也就是在0頁中管理編號為n的頁。如果n為16384~2*16384-1,則對應的簇頁為16384,以此類推。我們看下具體的代碼: ~~~ /************************************************************************ Calculates the page where the descriptor of a page resides. */ UNIV_INLINE ulint xdes_calc_descriptor_page( /*======================*/ ??????????????????????????? /* out: descriptor page offset */ ?????? ulintoffset)??????????? /* in: page offset */ { ?????? ut_ad(UNIV_PAGE_SIZE > XDES_ARR_OFFSET ????????????? + (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE) * XDES_SIZE); //參數offset為我們需要計算的頁號 // XDES_DESCRIBED_PER_PAGE為16384 ?????? return(ut_2pow_round(offset, XDES_DESCRIBED_PER_PAGE)); } /***************************************************************** Calculates fast a value rounded to a multiple of a power of 2. */ UNIV_INLINE ulint ut_2pow_round( /*==========*/????????? /* out: value of n rounded down to nearest ???????????????????? multiple of m */ ?????? ulintn,??? /* in: number to be rounded */ ?????? ulintm)?? /* in: divisor; power of 2 */ { ?????? ut_ad(0x80000000UL % m == 0); //在本例子中,m為16384 // m – 1對應的二進制為00000000000000000111111111111111 //~(m - 1)為11111111111111111000000000000000 // n & ~(m - 1)相當于將n最低的15位置0 //相當于 n-n%16384 ?????? return(n & ~(m - 1)); } ~~~ 因此,通過函數xdes_calc_descriptor_page就可以知道給定頁所在的簇頁。 接著有帶來一個算法,該給定頁對應的簇描述結構是簇頁的第幾個簇描述結構(從0開始編碼)。見下面的代碼: ~~~ /************************************************************************ Calculates the descriptor index within a descriptor page. */ UNIV_INLINE ulint xdes_calc_descriptor_index( /*=======================*/ ??????????????????????????? /* out: descriptor index */ ?????? ulintoffset)??????????? /* in: page offset */ { //步驟1:ut_2pow_remainder的作用是offset % 16384=n //步驟2:FSP_EXTENT_SIZE的值是64,那么對應的簇描述結構就是n/64 //舉例,假設offset為16386,那么n為2(16386%16384) //一個簇頁描述16384個頁,第一個簇描述的頁對應的n為0-63,雖然這里n為2,實際上描述的頁號是16384(該簇頁的頁號)+2=16386 //n為2,對應的第0個簇(n/64) ?????? return(ut_2pow_remainder(offset, XDES_DESCRIBED_PER_PAGE) / ???????????????????????????????????????????????? FSP_EXTENT_SIZE); } /***************************************************************** Calculates fast the remainder when divided by a power of two. */ UNIV_INLINE ulint ut_2pow_remainder( /*==============*/? /* out: remainder */ ?????? ulintn,??? /* in: number to be divided */ ?????? ulintm)?? /* in: divisor; power of 2 */ { ?????? ut_ad(0x80000000UL % m == 0); ?????? return(n & (m - 1)); } ~~~ 通過這個代碼,就可以得到給定頁對應簇頁中的第幾個簇描述結構。我們再看下實際的調用,見最后一個函數的調用。 ~~~ /************************************************************************ Gets pointer to a the extent descriptor of a page. The page where the extent descriptor resides is x-locked. If the page offset is equal to the free limit of the space, adds new extents from above the free limit to the space free list, if not free limit == space size. This adding is necessary to make the descriptor defined, as they are uninitialized above the free limit. */ UNIV_INLINE xdes_t* xdes_get_descriptor_with_space_hdr( /*===============================*/ ??????????????????????????? /* out: pointer to the extent descriptor, ??????????????????????????? NULL if the page does not exist in the ??????????????????????????? space or if offset > free limit */ ?????? fsp_header_t*sp_header,/* in: space header, x-latched */ ?????? ulint??????? space,???? /* in: space id */ ?????? ulint??????? offset,???? /* in: page offset; ??????????????????????????? if equal to the free limit, ??????????????????????????? we try to add new extents to ??????????????????????????? the space free list */ ?????? mtr_t*??????????? mtr)/* in: mtr handle */ { ?????? ulintlimit; ?????? ulintsize; ?????? ulintdescr_page_no; ?????? page_t*?? descr_page; ?????? ut_ad(mtr); ?????? ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space), ????????????????????????????????????????? MTR_MEMO_X_LOCK)); ?????? /* Read free limit and space size */ ?????? limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr); ?????? size? = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr); ?????? /* If offset is >= size or > limit, return NULL */ ?????? if ((offset >= size) || (offset > limit)) { ????????????? return(NULL); ?????? } ?????? /* If offset is == limit, fill free list of the space. */ ?????? if (offset == limit) { ????????????? fsp_fill_free_list(FALSE, space, sp_header, mtr); ?????? } ?????? descr_page_no = xdes_calc_descriptor_page(offset); ?????? if (descr_page_no == 0) { ????????????? /* It is on the space header page */ ????????????? descr_page = buf_frame_align(sp_header); ?????? } else { ????????????? descr_page = buf_page_get(space, descr_page_no, RW_X_LATCH, mtr); #ifdef UNIV_SYNC_DEBUG ????????????? buf_page_dbg_add_level(descr_page, SYNC_FSP_PAGE); #endif /* UNIV_SYNC_DEBUG */ ?????? }???? ? //看這里 ? //第0個簇結構相當于簇頁頭的偏移量為XDES_ARR_OFFSET ? //定義:#define? XDES_ARR_OFFSET????????? (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) ? //FSP_HEADER_OFFSET的值為38,這個是每個頁都有的,在第11篇文章中有描述 ? //定義:#define? FSP_HEADER_SIZE??????????? (32 + 5 * FLST_BASE_NODE_SIZE) ? //#define???? FLST_BASE_NODE_SIZE??? (4 + 2 * FIL_ADDR_SIZE) ? //#define???? FIL_ADDR_SIZE?? 6???? /* address size is 6 bytes */ ? //因此FSP_HEADER_SIZE為112 ? //所以XDES_ARR_OFFSET為38+112=150 ?????? return(descr_page + XDES_ARR_OFFSET ?????? ?????? + XDES_SIZE * xdes_calc_descriptor_index(offset)); } ~~~ 通過這個函數就可以得到給定頁對應的簇描述結構。這里面需要提示一點的是,FSP_HEADER_SIZE是有意義的,用于描述表空間。 看下該結構的描述: /*????????????????? SPACE HEADER?????????? ???????????????????? ============ ? File space header data structure: this data structure is contained in the first page of a space. The space for this header is reserved in every extent descriptor page, but used only in the first. */ ?從中可以看出,每個簇頁都有這樣一個結構,但是只有第一個簇頁有效,也就是第0個文件的第0個文件。在如下的配置中,也就是ibdata1文件的第0頁。 [mysqld] innodb_data_file_path = ibdata1:10M;ibdata2:10M:autoextend 關于描述符,就這么多。具體的細節,建議查看代碼。 ” Bingxi:“ok,今天就這么多吧” Alex:“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>

                              哎呀哎呀视频在线观看