InnoDB儲存引擎之InnoDB關鍵特性,儲存innodb

來源:互聯網
上載者:User

InnoDB儲存引擎之InnoDB關鍵特性,儲存innodb
1.插入緩衝
    A.Insert Buffer
        聽名字會讓人理解為插入緩衝是緩衝池中的一部分。其實不是這個樣子的,InnoDB緩衝池中有Insert Buffer資訊,但是Insert Buffer和資料頁一樣,也是物理頁的一個組成部分。在InnoDB儲存引擎中,行記錄的插入順序是按照主鍵遞增的順序進行插入的。因此插入叢集索引(Primary Key)一般是順序的,不需要磁碟的隨機讀取。但是並不是所有的主鍵都是順序的。如主鍵是UUID這類的,那麼插入和輔助索引一樣都是隨機的。所以在建表時主鍵是關鍵一般都是自增ID且非空。
        對於非叢集索引的插入或者更新操作,不是每一次直接插入到索引頁中,而是先判定插入的非叢集索引頁是否在緩衝池中,若在則直接插入;如不在則先放入到Inset Buffer中。然後再以一定的頻率和情況進行Insert Buffer和輔助索引頁子節點的merge操作。這時通常能將多少插入合并到一個操作中(因為在一個索引頁中),這就大大提高了對於非叢集索引的效能。但是Inset Buffer的使用需要同時滿足一下兩個條件:1.索引是輔助索引;2.索引不是唯一的。如果是唯一索引的話,資料庫會去尋找索引頁來判斷插入記錄的唯一性,這個樣子又會有離散讀取的情況發生,從而導致Insert Buffer失去意義。可以通過命令show engine innodb status來查看插入緩衝的資訊。但是在寫密集的情況下,插入緩衝會佔用過多的緩衝池,預設最大可以佔到這個緩衝池的1/2。這對於其他的操作可能會帶來一定的影響。Percona發布一些patch來修正這個情況。可以通過ibuf_pool_size_per_max_size參數來設定。具體的可以到官網進行尋找。
    B.Change Buffer

        InnoDB從1.0.x版本開始引入了Change Buffer。對DML操作-insert、delete、update都進行緩衝。分別是:Insert Buffer、Delete Buffer、Purge Buffer。Change Buffer使用的對象依然是非唯一的輔助索引。對一條記錄進行update操作可能分為兩個過程:1.將記錄標記未已刪除;2.真正將記錄刪除。因此delete Buffer對呀update操作的第一個過程,Purge Buffer對應update操作的第二個過程。可以通過參數innodb_change_buffering來開啟各種Buffer的選項。該參數的可選值有:inserts、deletes、purges、all、none。changes表示啟用inserts和deletes,all表示啟用所有,none表示都不啟用。預設all。在InnoDB 1.2.x還可以通過參數innodb_change_buffer_max_size(百分比)來控制最大使用的記憶體數量。


        有圖可以看到這裡顯示了merged Operations和discarded operations。並且下邊都具體顯示Change Buffer中每個操作的次數。insert表示Insert Buffer;delete mark表示Delete Buffer;delete表示 Purge Buffer;discarded Operations表示當Change Buffer發生merge時,表已經被刪除,此時就無需將記錄合并到輔助索引中。
    C.Insert Buffer的內部實現
        在Mysql 4.1之前的版本中每張表都有一棵insert buffer B+樹。而現在的版本中只有一棵全域的insert buffer B+樹,負責對所有的表的非唯一輔助索引進行Insert Buffer。而這棵B+樹放在共用資料表空間中。因此,試圖通過獨立資料表空間ibd檔案恢複表中的資料時,往往會導致check table失敗。這是因為表的輔助索引中的資料可能還在Insert Buffer中,所以通過ibd檔案恢複後,還需要通過repair table來重建表中的輔助索引。

        Insert Buffer是一棵B+樹,因此也由分葉節點和非分葉節點組成,非分葉節點存放的是查詢額search key(鍵值),具體構造如:


        search key共佔用9個位元組,其中space(佔用4個位元組)表示待插入記錄所在表的資料表空間id(在InnoDB儲存引擎中,每個表都有一個唯一的space id,可以通過space id查詢得到是那張表)。marker佔用1位元組,用來相容老版本的Insert Buffer。offset表示頁所在的位移量,佔4位元組。

        當一個輔助索引要插入到頁(space, offset)時,如果這個頁不在緩衝池中,那麼InnoDB儲存引擎首先根據上述規則構造一個search key,接下來查詢Insert Buffer這棵B+樹,然後將這條記錄插入到Insert Buffer B+樹的分葉節點。對於插入到InnoDB Buffer B+樹的分葉節點的記錄,並不是直接插入,而是需要根據如下的規則進行構造:


        space、marker、offset欄位的含義和非分葉節點的含義相同。metadata佔用4位元組,其儲存的內容如下:


        IBUF_REC_OFFSET_COUNT儲存2位元組的整數,用來排序每個記錄進入Insert Buffer的順序。從Insert Buffer分葉節點的第5列開始,就是實際插入記錄的各個欄位啦。因此較之原插入記錄,Insert Buffer B+樹需要額外13位元組的開銷。

        因為啟用Insert Buffer索引後,輔助索引頁(space, page_no)中的記錄可能被插入到Insert Buffer B+樹中,所以為了保證每次Merge Insert Buffer頁必須成功,還需要有一個特殊的頁用來標記每個輔助索引頁(space,page_no)的可用空間。這個頁的類型稱之為Insert Buffer Bitmap。每個Insert Buffer Bitmap頁用來追蹤16384(256個區(Extent))個輔助索引頁,每個Insert Buffer Bitmap頁都在16384個頁的第二個頁中。每個輔助索引頁在Insert Buffer Bitmap頁中佔用4位(bit),具體結構如下:


    D.Merge Insert Buffer
        概括地說,Merge Insert Buffer的操作可能發生在以下幾種情況:
            1.輔助索引頁被讀取到緩衝池時;
            2.Insert Buffer Bitmap頁追蹤到該輔助索引頁頁無可用空間;
            3.Master Thread;
        第一種情況為當輔助索引頁被讀取到緩衝池時,列如這在執行SELECT查詢操作,這時需要檢查Insert Buffer Bitmap頁,然後該輔助索引頁是否有記錄存放在Insert Buffer B+樹中。有則將Insert Buffer B+樹中該頁的記錄插入到輔助索引索引頁中。
        第二種情況是,Insert Buffer Bitmap頁用來追中每個輔助頁的可用空間,並至少有1/32頁的空間,若插入輔助索引記錄時檢測到插入記錄後可用空間小於1/32頁,則會強制進行一次合并,即強制讀取輔助索引頁,將Insert Buffer B+樹中該索引頁的記錄及待插入的記錄插入到輔助索引頁中。
        第三種情況,在Master Thread線程中每秒活每10秒進行一次Merge Insert Buffer的操作。不同之處在於每次進行Merge操作頁的數量不一樣。每次Merge操作的不止一個頁,而是根據srv_innodb_io_capactiy的百分比來決定真正要合并多少個輔助索引頁。在Insert Buffer B+樹中,輔助索引頁根據(space, offset)都已排序好,故可以根據(space, offset)的排序次序進行頁的選擇。然而,對於Insert Buffer頁的選擇,InnoDB儲存引擎並非採用這個方式,它隨機地選擇Insert Buffer B+樹的一個頁,讀取該頁中的space及以後所需要數量的頁。若進行merge時,要進行merge操作的表已經被刪除,此時可以直接丟棄已經被Insert/Change Buffer的資料記錄。

2.兩次寫

    Insert Buffer使InnoDB儲存引擎的效能提升,而doublewrite(兩次寫)帶給InnoDB儲存引擎的資料頁的可靠性。這是因為,當資料庫宕機是,InnoDB儲存引擎可能正在寫入某個頁到表中,而這個時候唯寫了一部分(如16K的頁,唯寫了前4K),這情況被稱為部分寫失效(partial page write)。可能你會想著用重做日誌進行恢複。這是一個辦法。但是重做日誌記錄的是對頁的物理操作,如位移量800,寫'aaaa'記錄。如果這個頁本身已經發生啦損壞,在對其進行重做是沒有意思的。這就是在應用重做日誌前,需要一個頁的副本,當寫入失效時,先通過頁的副本來還原該頁,再進行重做。這就是doublewrite。如


    doublewrite由兩部分組成,一部分是記憶體中的doublewrite buffer,大小為2M,另一部分為物理磁碟上共用資料表空間中連續的128個頁(即2個區(extent))大小也是2M。在對緩衝池中的髒頁進行重新整理是,並不是直接寫入磁碟,而是通過memcpy函數將髒頁複製到記憶體中的doublewrite buffer,之後通過doublewrite buffer分兩次,每次1M順序的寫入共用資料表空間的物理磁碟上,然後馬上調用fsync函數,同步磁碟,避免緩衝寫帶來的問題。在完成doublewrite頁的寫入後,在將doublewrite buffer中的頁寫入各個資料表空間檔案中,這個時候的寫入是離散的。可以通過命令show global status like '%innodb_dblwr%';


    可以看到doublewrite一共寫了1413988個頁,但實際寫入次數為111623。如果innodb_dblwr_pages_written:innodb_dblwr_writes小於64:1,說明系統寫入壓力並不是很高。參數innodb_buffer_pool_pages_flushed表示當前從緩衝池中重新整理到磁碟頁的數量。從上邊介紹的可以知道,在生產環境中如果需要統計資料的寫入量,最安全的方法還是應該通過innodb_dblwr_pages_written參數進行通過。可以通過參數innodb_doublewrite來設定設定是否開啟doublewrite功能。skip_innodb_doublewrite也可以禁止使用doublewrite功能。
    注意:有些檔案系統本身就提供了部分寫失效的防範機制,如ZFS檔案系統。在這種情況下,就可以不用啟用doublewrite。
3.自適應雜湊索引
    雜湊是一種非常快的尋找方法,在一般情況時間複雜度為O(1)。而B+樹的尋找次數,取決於B+樹的高度,在產生環境中,B+樹的高度一般為3-4層,不需要查詢3-4次。InnoDB儲存引擎會監控對錶上各索引頁的查詢。如果觀察到簡曆雜湊索引可以提升速度,這簡曆雜湊索引,稱之為自適應雜湊索引(Adaptive Hash Index, AHI)。AHI是通過緩衝池的B+樹頁構造而來的。因此建立的速度非常快,且不要對整張表構建雜湊索引。InnoDB儲存喲inquiry會自動根據房屋的頻率和陌生來自動的為某些熱點頁建立雜湊索引。

    AHI有一個要求,對這個頁的連續訪問模式(查詢條件)必須一樣的。例如聯合索引(a,b)其訪問模式可以有以下情況:1.WHERE a=XXX;2.WHERE a=xxx AND b=xxx。若交替進行上述兩張查詢,InnoDB儲存引擎不會對該頁構造AHI。此外AHI還有如下要求:a.以該模式訪問了100次;b.頁通過該模式訪問了N次,其中N=頁中記錄/16。根據官方文檔顯示,啟用AHI後,讀取和寫入的速度可以提高2倍,負責索引的連結操作效能可以提高5倍。其設計思想是資料庫自由化的,無需DBA對資料庫進行人為調整。


    由可以看到AHI的使用資訊,包括AHI的大小、使用方式、每秒使用AHI搜尋的情況。雜湊索引只能用來查詢等值的情況,而對於其他類型是不能使用雜湊索引的。因此這裡出現non-hash searches/s。可以通過參數innodb_adaptive_hash_index來決定是否開啟。
4.非同步IO
    為了提高磁碟操作效能,當前的資料庫系統都採用非同步IO(AIO)。在InnoDB 1.1.x之前,AIO的實現是通過InnoDB儲存引擎中的代碼來類比的。但是從這之後,提供了核心層級的AIO的支援,稱為Native AIO。Native AIO需要作業系統提供支援。Windows和Linux都支援,而Mac則未提供。在選擇MySQL資料庫伺服器的作業系統時,需要考慮這方面的因素。MySQL可以通過參數innodb_use_native_aio來決定是否啟用Native AIO。在InnoDB儲存引擎中,read ahead方式的讀取都是通過AIO完成,髒頁的重新整理,也是通過AIO完成。
5.重新整理鄰接頁
    InnoDB儲存引擎在重新整理一個髒頁時,會檢測該頁所在區(extent)的所有頁,如果是髒頁,那麼一起重新整理。這樣做的好處是通過AIO可以將多個IO寫操作合并為一個IO操作。該工作機制在傳統機械磁碟下有顯著優勢。但是需要考慮下吧兩個問題:a.是不是將不怎麼髒的頁進行寫入,而該頁之後又會很快變成髒頁?b.固態硬碟有很高IOPS,是否還需要這個特性?為此InnoDB儲存引擎1.2.x版本開始提供參數innodb_flush_neighbors來決定是否啟用。對於傳統機械硬碟建議使用,而對於固態硬碟可以關閉。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.