1. 程式人生 > 實用技巧 >MySQL技術內幕Charpter2Innodb

MySQL技術內幕Charpter2Innodb

一、InnoDB體系架構

內部有多個記憶體塊組成記憶體池,用於:

1.維護程序執行緒要訪問的內部資料結構

2.快取磁碟資料

3.重做日誌緩衝

二、後臺執行緒

1.Master Thread

緩衝池中資料重新整理到磁碟,確保資料一致性

2.IO Thread

AIO處理寫請求,IO thread負責這些請求的回撥處理

3.PurgeThread

當事務提交後,undolog可能不在需要,purge用於回收已使用並分配的undo頁

4.PageCleanerThread

髒頁的重新整理工作從MasterThread中提取出來,1.2x引入

三、記憶體

1.緩衝池

對於資料庫中頁的修改,先修改緩衝池中的頁,再按一定頻率重新整理到磁碟上,由Checkpoint機制觸發。

innodb_buffer_pool_size

其中快取資料頁型別包括:索引頁、資料頁、undo頁等

允許多個緩衝池例項,頁根據hash分配到不同例項中,減少資源競爭

2.LRU List Free List Flush List

通過midpoint將最新訪問的頁放在LRU列表的midpoint位置,主要因為某些SQL操作會導致索引或資料的掃描,會訪問較多甚至全部的頁,但其中一些頁並不是熱點資料,若放在首部位置將可能把真正的熱點資料從列表中移出。

資料庫啟動時所有頁放在Free列表中,當需要從緩衝池中分頁時先去FreeList中查詢,若有則加入LRUList中。

SHOW_ENGINE_INNODB_STATUS觀察LRU與Free使用情況

Buffer poolhit rate表示快取的命中率,不應小於95%

unzip_LRU將原本16KB頁進行壓縮,利用夥伴演算法進行記憶體的分配

當LRUList中頁被修改後,變為髒頁,而FlushList中頁即為髒頁;LRU管理緩衝池中頁的可用性,Flush則管理將頁重新整理到磁碟

Modified db pages髒頁數量

3.重做日誌緩衝

InnoDB將重做日誌資訊先放入此緩衝區,再按頻率重新整理到重做日誌檔案。innodb_log_buffer_sizedefault 8M

1.Master Thread每秒重新整理

2.每個事務提交重新整理

3.重做日誌緩衝池剩餘空間小於1/2時重新整理

4.額外的記憶體池

對一些資料結構本身的記憶體進行分配需從額外記憶體池中申請,p31

四、Checkpoint

為避免將資料重新整理到磁碟時宕機丟失資料,採用WriteAhead Log策略,即事務提交時先寫redo log,再修改頁。但存在兩個前提:1.緩衝池可以快取所有資料庫資料;2.redo log可無限增大。且恢復時間可能較久。

Checkpoint主要解決:1.縮短資料庫恢復時間;2.緩衝池不夠用,將髒頁重新整理到磁碟;3.redo log不可用時重新整理髒頁。

通過LSN標記版本。

可分為1.Sharp Checkpoint,default,資料庫關閉時將髒頁重新整理到磁碟;2.FuzzyCheckpoint執行時重新整理一部分髒頁

主要有以下幾種情況:

1.MasterThread Checkpoint

2.FLUSH_LRU_LIST 確保LRU中有約100個頁可用

3.Async/Sync Flush redo log不可用;確保redo log迴圈使用

4.Dirty Page too much

五、MasterThread

1.0x前

具有最高執行緒優先順序,包含多種迴圈,根據資料庫狀態在多個迴圈間進行切換。

1.loop主迴圈分為每秒與每10秒

每秒包括:

1.日誌緩衝重新整理到磁碟,即使事務還沒提交(總是);

2.合併插入緩衝(IO壓力小時,次數<5);

3.至多重新整理100個髒頁到磁碟(髒頁比例>90%);等

每10秒:

1.重新整理100個髒頁到磁碟(可能);

2.合併至多5個插入緩衝(總是);

3.將日誌緩衝重新整理到磁碟(總是);

4.刪除無用的undo頁(總是,full purge);

5.重新整理100或10個髒頁到磁碟(總是)。

2.background loop

資料庫空閒或關閉時切換到此迴圈,執行:

1.刪除無用undo頁(總是);

2.合併20個插入緩衝(總是);

3.跳回主迴圈(總是);

4.不斷重新整理100個頁直到符合條件(可能,跳轉flushloop)。

1.2x前

1.0x中對IO存在限制。

引入innodb_io_capacity

1.2x

重新整理髒頁由MasterThread分離到PageCleaner Thread

六、關鍵特性

1.插入緩衝

1.insert buffer:主鍵為聚集索引,記錄插入時按照主鍵遞增順序,不需要磁碟隨機讀取。但是當使用其他非聚集索引時,且非唯一,此時進行插入時,資料頁存放仍是按主鍵順序,非聚集索引頁子節點插入為離散,而隨機讀取導致插入操作效能下降。故引入insert buffer先判斷插入非聚集索引是否在緩衝池中,若在,直接插入,不在,則先放入insert buffer中。然後再以一定頻率和情況進行insert buffer和輔助索引頁的merge,將多個插入合併到一個操作中,從而提高非聚集索引的插入效能。

2.change buffer

對DML操作進行緩衝

3.insert buffer內部實現

通過全域性B+樹對所有表的輔助索引進行insertbuffer,非葉節點存放search key

4.merge insert buffer

1.輔助索引頁被讀取到緩衝池中;

2.insertbuffer bitmap追蹤該輔助索引頁已無可用空間時;

3.Master Thread

2.兩次寫

doublewrite用於保證資料頁可靠性

當innodb寫入某個頁到表的過程中發生宕機,導致頁損壞,無法通過redo log進行恢復時,需要用該頁的副本先進行還原,再進行redo ,即為doublewrite

doublewrite包括兩個部分,記憶體中doublewritebuffer與共享表空間128個頁,當髒頁重新整理時,通過memcpy將髒頁先複製到記憶體buffer中,通過buffer分為兩次,每次1M順序的寫入到共享表空間物理磁碟上,然後呼叫fsync,同步磁碟,整個過程為順序寫入。完成doublewrite頁寫入後,再將buffer中頁寫入各個表空間檔案中,此時寫入為離散的。

3.自適應hash索引

時間複雜度低,O(1),但是對頁的連續訪問模式必須一致,即查詢條件一致,且以該模式訪問100次

4.AIO

優勢在於IOMerge

5.重新整理鄰近頁

當重新整理一個髒頁時,會檢測該頁所在區,若有髒頁則一起重新整理,且可通過AIO將多個寫入合併為一個IO操作