標籤:insert 資訊
Innodb體繫結構
記憶體緩衝池
-
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,壓縮頁大小為1、2、4、8KB,其還是屬於LRU管理。unzip_LRU對不同大小頁分開管理,採用夥伴演算法分配記憶體。
redo log buffer
redo log先都寫入該buffer,而後按一定頻率重新整理到磁碟(1s/次),預設8M。其刷到磁碟主要一下幾個情況:
-
Master Thread每秒執行一次。
-
事物提交時。
-
redo log buffer剩餘空間小於1/2。
額外的記憶體池
對一些資料結構本身的記憶體配置是從額外記憶體池分配。
線程Master Thread
負責將緩衝池中的資料非同步重新整理到磁碟,包括髒頁。合并插入緩衝(INSERT BUFFER)、UNDO頁的回收等。
IO Thread
Innodb中大量使用AIO處理寫請求,IO Thread則主要處理這些請求的回調,包括write、read、insert buffer和log IO Thread。
Purge Thread
主要用來回收undo log,Innodb1.1之前由Master Thread負責。
Page Cleaner Thread
清理已提交事物的UNDO log。
Checkpoint
事務型資料庫一般採用Write Ahead Log策略,當事物提交時先寫redo log而後修改記憶體中的頁。當資料庫宕機對於還未寫入磁碟的修改資料可以通過redo log恢複。Checkpoint作用在於保證該點之前的所有修改的頁均已重新整理到磁碟,這之前的redo log在恢複資料時可以不需要了。
Sharp Checkpoint
發生在資料庫關閉時,將所有髒頁寫入磁碟,資料庫運行時一般不使用。
Fuzzy Checkpoint
只重新整理部分部分髒頁。
-
Master Thread Checkpoint:Master Thread非同步已一定頻率重新整理一定比例髒頁。
-
Flush_LRU_LIST Checkpoint:為了保證LRU中有一定數量的空閑頁,Page Clear Thread將對LRU中尾端頁進行移除,如果存在髒頁則做重新整理。
-
Async/Sync Flush Checkpoint:為了保證redo log迴圈使用(覆蓋),對於需要將redo檔案中停用髒頁進行重新整理到磁碟。
-
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 i 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執行。
+ View Code
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/32,則強制進行合并。
-
Master Thread中的合并插入緩衝。
兩次寫
在對髒頁重新整理到磁碟時,如果某一頁還沒寫完就宕機,此時該頁資料已經混亂無法通過redo實現恢複。innodb提供了doublewrite機制,其重新整理髒頁步驟如下:
|
1
2
3 |
1. 先將髒頁資料複製到doublewrite buffer中(2MB記憶體)
2. 將doublewrite buffer分兩次,每次1MB寫入到doublewrite磁碟(2MB)中。
3. 馬上同步髒頁資料到磁碟。對於資料混亂的頁則可以從doublewrite中讀取到,該頁寫到共用資料表空間。
|
自適應雜湊索引
InnoDB儲存引擎會監控對錶上索引的尋找,如果觀察到建立雜湊索引可以帶來速度的提升,則建立雜湊索引,所以稱之為自適應(adaptive) 的。自適應雜湊索引通過緩衝池的B+樹構造而來,因此建立的速度很快。而且不需要將整個表都建雜湊索引,InnoDB儲存引擎會自動根據訪問的頻率和模式 來為某些頁建立雜湊索引。
非同步IO
linux和windows中提供非同步IO,其可以對連續的頁做合并連續頁的IO操作使隨機IO變順序IO。
重新整理鄰接頁
重新整理頁時判斷相鄰頁是否也是髒頁。
Mysql Innodb體繫結構