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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在上一篇里,bingxi和alex聊了關于mysql內核調試方法。前10篇是一些基礎性的內容,從本篇開始,將開始描述inndob的存儲結構,為了便于描述的方便,會將一些細節暫時隱去,在后續說到B時會串起來。 我們可以了解到oracle、sqlserver采用的是段、簇、頁的方式進行管理。很多其他的數據庫也是采用的這樣的方法。本篇,bingxi和alex討論的是頁的編號。 對應的文件為: D:/mysql-5.1.7-beta/storage/innobase/fil/fil0fil.c D:/mysql-5.1.7-beta/storage/innobase/include/fil0fil.h Bingxi:“alex,我們的初級系列終于開始進入存儲部分了。存儲這邊內容,包含的還是比較多。Innodb共享存儲空間而言(獨立表空間也是一樣,這里我們只分析共享表空間),以固定大小劃分了很多個頁。假設共享存儲空間只有一個文件,那么編號就是從0開始,默認頁大小為16k。也就是文件的大小,按照16k進行劃分。假設是10M,那么就是劃分為640頁,編號從0-639。 ![](https://box.kancloud.cn/2016-07-22_5791c9c355bfe.gif) 現在問題來了,如果是多個文件呢,如何編號。Alex,你來看看。提示下,mysql的共享表空間,只允許最后一個文件為可擴展的。 ” Alex:“ok,我們通過代碼來看這個問題。我們先配置下my.ini,內容如下: [mysqld] innodb_data_file_path = ibdata1:10M;ibdata2:10M:autoextend 我們看下fil_io代碼的實現, ~~~ /************************************************************************ Reads or writes data. This operation is asynchronous (aio). */ ulint fil_io( /*===*/ ??????????????????????????? /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED ??????????????????????????? if we are trying to do i/o on a tablespace ??????????????????????????? which does not exist */ ?????? ulinttype,????????????? /* in: OS_FILE_READ or OS_FILE_WRITE, ??????????????????????????? ORed to OS_FILE_LOG, if a log i/o ??????????????????????????? and ORed to OS_AIO_SIMULATED_WAKE_LATER ??????????????????????????? if simulated aio and we want to post a ??????????????????????????? batch of i/os; NOTE that a simulated batch ??????????????????????????? may introduce hidden chances of deadlocks, ??????????????????????????? because i/os are not actually handled until ??????????????????????????? all have been posted: use with great ??????????????????????????? caution! */ ?????? ibool?????? sync,????????????? /* in: TRUE if synchronous aio is desired */ ?????? ulintspace_id,/* in: space id */ ?????? ulintblock_offset,?? /* in: offset in number of blocks */ ?????? ulintbyte_offset,??? /* in: remainder of offset in bytes; in ??????????????????????????? aio this must be divisible by the OS block ??????????????????????????? size */ ?????? ulintlen,???????? /* in: how many bytes to read or write; this ??????????????????????????? must not cross a file boundary; in aio this ??????????????????????????? must be a block size multiple */ ?????? void*????? buf,??????? /* in/out: buffer where to store read data ??????????????????????????? or from where to write; in aio this must be ??????????????????????????? appropriately aligned */ ?????? void*????? message)/* in: message for aio handler if non-sync ??????????????????????????? aio used, else ignored */ { ?????? ?????? //1.找到對應的表空間結構 ?????? HASH_SEARCH(hash, system->spaces, space_id, space, ???????????????????????????????????????????????? space->id == space_id); ?…… ? //2.取得第一個文件結點 ?????? node = UT_LIST_GET_FIRST(space->chain); ?????? for (;;) { ????????????? …… ??????? //文件的大小根據my.ini的配置而定 ????????????? //第一個文件ibdata1是10M,因此對應的node->size為640 ????????????? //第二個文件ibdata2是10M,因此對應的node->size為640 ????????????? //3.假設我們查找的文件號為0-639,則對應為第一個文件。 ????????????? if (node->size > block_offset) { ???????????????????? /* Found! */ ???????????????????? break; ????????????? } else { //4.假設我們查找的文件號>640,則查看是否在第二個文件中。 //假設是640,則在第二個文件的偏移量為0*16k字節處開始的一頁,也就是文件開始處,也可以勉強稱為第二個文件的第0頁,實際上是640頁。 //假設是641,則在第二個文件的偏移量為(641-640)*16k字節處開始的一頁,也可以勉強稱為第二個文件的第1頁,實際上是641頁。 ???????????????????? block_offset -= node->size; ???????????????????? node = UT_LIST_GET_NEXT(chain, node); ????????????? } ?????? }??????????? ? …… ? //5.計算偏移量,見前面代碼中的block_offset ?????? offset_high = (block_offset >> (32 - UNIV_PAGE_SIZE_SHIFT)); ?????? offset_low? = ((block_offset << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL) ???????????????????? + byte_offset; ? …… //6.進行aio操作,offset_low指相對于文件頭的字節偏移,len指長度,即獲得長度,通常為16k ????? ret = os_aio(type, mode | wake_later, node->name, node->handle, buf, ??????????????????????????? offset_low, offset_high, len, node, message); ? …… ?????? return(DB_SUCCESS); } ~~~ 因此,兩個文件時的頁編號在本例中如圖2: ![](https://box.kancloud.cn/2016-07-22_5791c9c36d853.gif) 同樣,假設有3個文件。對應的大小分別為xMB,yMB,zMB。則第一個文件的編號為0---x*1024/16-1,第二個文件的編號為x*1024/16---(x+y)*1024/16-1,第三個文件的頁編號為(x+y)*1024/16---(x+y+z)*1024/16-1。最后一個文件的大小是可變的,可參考fil相關代碼。 Bingxi,頁編號就是這么回事情了。每個頁會一個編號,因此在每一頁的開始處,會有38個字節用于描述本頁。定義的是相對于頁頭的偏移量。 ~~~ /* The byte offsets on a file page for various variables */ #define FIL_PAGE_SPACE_OR_CHKSUM 0??? /* in < MySQL-4.0.14 space id the ?????????????????????????????????? page belongs to (== 0) but in later ?????????????????????????????????? versions the 'new' checksum of the ?????????????????????????????????? page */ //這里記錄的是頁號 #define FIL_PAGE_OFFSET????????????? 4???? /* page offset inside space */ //有時候頁是連在一起的,比如所引頁,這里通過prev和next指向前一頁,后一頁。 //需要注意的是,假設本頁是第n頁,下一頁不需要是n+1,上一頁也不需要是n-1 #define FIL_PAGE_PREV?????????? 8???? /* if there is a 'natural' predecessor ?????? ??????????????????????????? of the page, its offset */ #define FIL_PAGE_NEXT?????????? 12??? /* if there is a 'natural' successor ?????????????????????????????????? of the page, its offset */ //頁中最新日志的日志序列號 #define FIL_PAGE_LSN???????????? 16??? /* lsn of the end of the newest ?????????????????????????????????? modification log record to the page */ //頁的類型 #define??? FIL_PAGE_TYPE???????? 24??? /* file page type: FIL_PAGE_INDEX,..., ?????????????????????????????????? 2 bytes */ #define FIL_PAGE_FILE_FLUSH_LSN???? 26??? /* this is only defined for the ?????????????????????????????????? first page in a data file: the file ?????????????????????????????????? has been flushed to disk at least up ?????????????????????????????????? to this lsn */ #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID? 34 /* starting from 4.1.x this ?????????????????????????????????? contains the space id of the page */ //這里的38表示的是長度 #define FIL_PAGE_DATA?????????? 38??? /* start of the data on the page */ ~~~ 因此文件劃分為很多頁,每一頁有38個字節用于描述頁頭。而我們知道的是,共享存儲空間是有很多數據庫共同使用的,假設有如下的操作順序: 1)? 創建表1,并插入數據 2)? 創建表2,并插入數據 3)? 表1插入數據 4)? 表2插入數據 如果我們每次分配一個頁,就會存儲得很凌亂。可能第n頁屬于t1,n+1頁屬于t2,n+3頁屬于t1,n+4頁屬于t2,…… 這樣會降低io讀寫性能,連續讀取性能會更好些,減少了磁頭的頻繁移動。Bingxi,你覺得mysql是怎么解決這個問題的呢? ” Bingxi:“ok,這里面就引出了一個新的結構:簇。簇是連續的頁,數量為64頁。這個我們下篇講。” 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>

                              哎呀哎呀视频在线观看