Mysql Innodb體系結構

Innodb體系結構

  • Innodb存儲引擎主要包括內存池以及後臺線程。
  • 內存池:多個內存塊組成一個內存池,主要維護進程/線程的內部數據、緩存磁盤數據,修改文件前先修改內存、redo log
  • 後臺線程:刷新內存池中的額

內存

緩衝池

  • Innodb的數據以頁的形式存儲在磁盤,所以採用內存做爲緩存頁數據。
  • 讀頁數據時,先將磁盤上的頁數據「FIX」到緩衝池,下次讀便可直接從緩衝池中讀。
  • 修改數據時,先修改緩衝池中的頁數據,而後刷新到磁盤,並非每次都刷新而是經過Checkpoint機制刷新到磁盤。
  • 數據頁類型:索引頁、數據頁、undo頁、插入緩衝(insert buffer)、自適應哈希索引、鎖信息、數據字典信息等
  • 緩存池經過LRU算法管理。

LRU、Free List、Flush List

  • 普通LRU:最頻繁的處於列表前端,最少使用處於尾端,先釋放列表尾端的頁。
  • Innodb LRU:在LRU隊列中加入midpoint位置,默認值5/8,表示新讀取的頁加入到列表的5/8位置。midpoint以後列表成爲old表,以前稱爲new表。即列表尾端到表尾37%爲old表,其他爲new表。new表存放活躍數據。
  • Free List:數據庫啓動時LRU表爲空,頁均存放在Free List中。須要使用時從該表中獲取。
  • Flush List管理緩存中被修改過的頁。
  • unzip_LRU,壓縮頁大小爲一、二、四、8KB,其仍是屬於LRU管理。unzip_LRU對不一樣大小頁分開管理,採用夥伴算法分配內存。

redo log buffer

redo log先都寫入該buffer,然後按必定頻率刷新到磁盤(1s/次),默認8M。其刷到磁盤主要一下幾個狀況:php

  1. Master Thread每秒執行一次。
  2. 事物提交時。
  3. redo log buffer剩餘空間小於1/2。

額外的內存池

對一些數據結構自己的內存分配是從額外內存池分配。html


線程

Master Thread

負責將緩存池中的數據異步刷新到磁盤,包括髒頁。合併插入緩存(INSERT BUFFER)、UNDO頁的回收等。前端

IO Thread

Innodb中大量使用AIO處理寫請求,IO Thread則主要處理這些請求的回調,包括write、read、insert buffer和log IO Thread。linux

Purge Thread

主要用來回收undo log,Innodb1.1以前由Master Thread負責。算法

Page Cleaner Thread

清理已提交事物的UNDO log。數據庫


Checkpoint

事務型數據庫通常採用Write Ahead Log策略,當事物提交時先寫redo log然後修改內存中的頁。當數據庫宕機對於還未寫入磁盤的修改數據能夠經過redo log恢復。Checkpoint做用在於保證該點以前的全部修改的頁均已刷新到磁盤,這以前的redo log在恢復數據時能夠不須要了。windows

Sharp Checkpoint

發生在數據庫關閉時,將全部髒頁寫入磁盤,數據庫運行時通常不使用。緩存

Fuzzy Checkpoint

只刷新部分部分髒頁。數據結構

  1. Master Thread Checkpoint:Master Thread異步已必定頻率刷新必定比例髒頁。
  2. Flush_LRU_LIST Checkpoint:爲了保證LRU中有必定數量的空閒頁,Page Clear Thread將對LRU中尾端頁進行移除,若是存在髒頁則作刷新。
  3. Async/Sync Flush Checkpoint:爲了保證redo log循環使用(覆蓋),對於須要將redo文件中不可用的髒頁進行刷新到磁盤。
  4. Dirty Page too much Checkpoint:髒頁數量太多。

Master Thread工做方式

Innodb 1.2.x以前

主要包括主loop、background loop、flush loop和suspend loop。其中的參數能夠配置。異步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
while ( true ){
 
     //差很少1s一次
     for ( int  in  0..9){
         刷新日誌緩存到磁盤
         //1s內的統計值
         if  IO < 5
             合併插入緩存
         if  髒頁比例 > 預約值
             刷新部分髒頁(不超過100)
         if   沒有用戶活動
             進入background loop{
                 刪除無用undo頁
                 合併20個插入緩衝
                 可能跳到flush loop{
                     可能跳到suspend loop
                 }
                 跳回主loop
             }
         sleep 1s;
     }
     //差很少10s一次
     if  IO < 200  //10s內
         刷新100個髒頁到磁盤
     合併最多5個插入緩衝
     刷新日誌緩衝
     刪除無用undo
     刷新100或10個髒頁
}

  

Innodb 1.2.x

Master Thread中的髒頁刷新功能徹底由Page Cleaner Thread執行。

  

nnodb關鍵特性

插入緩衝

  • 當插入數據須要更新非彙集索引時,若是每次都更新則須要進行屢次隨機IO,所以將這些值寫入緩衝對相同頁的進行合併提升IO性能。
  • 插入非彙集索引時,先判斷該索引頁是否在緩衝池中,在則直接插入。不然寫入到Insert Buffer對象。
  • 條件:二級索引,索引不能是unique(由於若是是unique則必須保證惟一性,此時得檢查全部索引頁,仍是隨機IO了)
  • Change Buffer:包括Insert Buffer、Delete Buffer、Purge Buffer,update操做包括將記錄標記爲已刪除和真正將記錄刪除兩個過程,對應後兩個Buffer。
  • Insert Buffer內部是一顆B+樹
  • Merge Insert Buffer三種狀況:
    1. 對應的索引頁被讀入緩衝池。
    2. 對應的索引頁的可用空間小於1/32,則強制進行合併。
    3. Master Thread中的合併插入緩衝。

兩次寫

在對髒頁刷新到磁盤時,若是某一頁還沒寫完就宕機,此時該頁數據已經混亂沒法經過redo實現恢復。innodb提供了doublewrite機制,其刷新髒頁步驟以下:

1. 先將髒頁數據複製到doublewrite buffer中(2MB內存)
2. 將doublewrite buffer分兩次,每次1MB寫入到doublewrite磁盤(2MB)中。
3. 立刻同步髒頁數據到磁盤。對於數據混亂的頁則能夠從doublewrite中讀取到,該頁寫到共享表空間。

  

自適應哈希索引

InnoDB存儲引擎會監控對錶上索引的查找,若是觀察到創建哈希索引能夠帶來速度的提高,則創建哈希索引,因此稱之爲自適應(adaptive) 的。自適應哈希索引經過緩衝池的B+樹構造而來,所以創建的速度很快。並且不須要將整個表都建哈希索引,InnoDB存儲引擎會自動根據訪問的頻率和模式 來爲某些頁創建哈希索引。

異步IO

linux和windows中提供異步IO,其能夠對連續的頁作合併連續頁的IO操做使隨機IO變順序IO。

刷新鄰接頁

刷新頁時判斷相鄰頁是否也是髒頁。

相關文章
相關標籤/搜索