你真的瞭解Innodb儲存引擎?

上古偽神發表於2021-04-11

前言

前幾篇記錄瞭如何檢視SQL執行計劃、資料庫事務相關的知識點

除了這兩個,資料庫還有兩個是非常重要的,必須要考的

就是儲存引擎和索引

今天先記錄以下InnoDB儲存引擎相關的知識點

MySQL儲存引擎

在MySQL儲存引擎中,最為廣知的儲存引擎是InnoDB和MyISAM儲存引擎

而這兩個儲存引擎的區別應該大家都清楚:

你真的瞭解Innodb儲存引擎?

 

而MySQL目前預設的儲存引擎就是InnoDB

「如何檢視錶使用的是哪種儲存引擎?」

show table status like 'table_name'\G
你真的瞭解Innodb儲存引擎?

 

InnoDB

是MySQL的預設事務性儲存引擎,最重要、使用最廣泛。

用來處理大量的短期事務。

InnoDB的效能和自動崩潰恢復特性,使得它在非事務性儲存的需求中也有廣泛的應用。

採用MVVC來支援高併發,並實現了四個標準的隔離級別,預設隔離級別是RR(Repeatable Read可重複讀),並通過間隙鎖來防止幻讀的出現。

InnoDB表是基於聚簇索引建立的,聚簇索引對主鍵查詢由很高的效能,不過它的二級索引(非主鍵索引)必須包含主鍵列。

「具體架構圖如下」

你真的瞭解Innodb儲存引擎?

 

上半部分是例項層(計算層),位於記憶體中

下半部分是物理層,位於檔案系統中

例項層

分為執行緒和記憶體,Innodb重要的執行緒有Master Thread,此執行緒是Innodb的主執行緒,負責排程其他各執行緒。

Master Thread 的優先順序最高, 其內部包含幾個迴圈:

主迴圈(loop)

後臺迴圈(background loop)

重新整理迴圈(flush loop)

暫停迴圈(suspend loop)。

Master Thread 會根據其內部執行的相關狀態在各迴圈間進行切換

大部分操作在主迴圈(loop)中完成,其包括1s和10s兩種操作:

「1s操作:」

日誌緩衝重新整理到磁碟

最多重新整理100個新髒頁到磁碟

執行並改變緩衝的操作

若當前沒有使用者活動,可能切換到後臺迴圈等


「10s操作:」

最多重新整理100個新髒頁到磁碟

合併至多5個被改變的緩衝

日誌緩衝重新整理到磁碟

刪除無用的Undo頁

重新整理 100 個或者 10 個髒頁到磁碟(總是)產生一個檢查點(總是)等。


「buf dump thread:」

將快取池中內容dump到磁碟中,實現MySQL熱啟動

「page_cleaner_thread:」

將快取池的髒頁重新整理到磁碟

「purge thread:」

將不再使用的Undo頁回收

「read_thread:」

處理讀請求,並負責將資料頁從磁碟中讀取出來

「write_thread:」

負責將資料頁從緩衝區寫入磁碟,page_cleaner 執行緒發起刷髒頁操作後就開始工作了。

「redo_log_thread:」

負責將日誌緩衝區中的內容重新整理到Redo log檔案中

「insert_buffer_thread:」

負責把 Insert Buffer 中的內容重新整理到磁碟


快取結構

你真的瞭解Innodb儲存引擎?

 

緩衝池中快取的資料頁型別有:

  • 索引頁
  • 資料頁
  • undo頁
  • 插入緩衝(insert buffer)
  • 自適應雜湊索引(adaptive hash index)
  • InnoDB儲存的鎖資訊(lock info)
  • 資料字典資訊(data dictionary)

你真的瞭解Innodb儲存引擎?

 

Redo log 日誌快取

InnoDB儲存引擎會首先將重做日誌資訊先放入重做日誌緩衝中,然後再按照一定頻率將其重新整理到重做日誌檔案


「緩衝頁管理演算法:」

頁:磁碟管理的最小單位,預設16K。型別有:資料頁,undo頁,系統頁

一般緩衝的管理演算法就是LRU(Least recently used)。

一般是把剛如緩衝頁的放在LRU的頭部,作為最近訪問的元素,最後的一個元素被淘汰。

(1)頁已經在緩衝池裡,那就只做“移至”LRU頭部的動作,而沒有頁被淘汰;

(2)頁不在緩衝池裡,除了做“放入”LRU頭部的動作,還要做“淘汰”LRU尾部頁的動作;

比如:有一個LRU鏈

你真的瞭解Innodb儲存引擎?

 

「第一種情況:」

查詢元素為0的,那麼連結串列就變成下面這樣子

你真的瞭解Innodb儲存引擎?

 

「第二種情況:」

查詢元素為10的,但10不在鏈中,所以將10新增到head,而tail節點6去除

你真的瞭解Innodb儲存引擎?

 

MySQL在此基礎上進行了改造,原因是:

(1)預讀失效:

「預讀:」

磁碟讀寫,並不是按需讀取,而是按頁讀取,一次至少讀一頁資料(一般是16K),如果未來要讀取的資料就在頁中,就能夠省去後續的磁碟IO,提高效率。

「預讀失效:」

預讀(Read-Ahead)提前把頁放入了緩衝池,但最終MySQL並沒有從頁中讀取資料,稱為預讀失效。

「如何優化?」

(1)讓預讀失效的頁,停留在緩衝池LRU裡的時間儘可能短;

(2)讓真正被讀取的頁,才挪到緩衝池LRU的頭部;


所以MySQL將LRU分成兩部分,分別是:

  • 新生代
  • 老生代

新老生代首位相連。

新頁加入緩衝池時,只加入老生代的頭部,

「如果資料真正被讀取(預讀成功),才會加入到新生代的頭部」

「如果資料沒有被讀取,則會比新生代裡的“熱資料頁”更早被淘汰出緩衝池」

新生代跟老生代的比例是 5 : 3

例如:綠色的是新生代,黃色是老生代

你真的瞭解Innodb儲存引擎?

 

如果插入一個9的頁,就是如下圖:

老年代最後一個被淘汰

你真的瞭解Innodb儲存引擎?

 

如果此時9被讀取,那麼就變成如下:

9稱為新生代head節點,而原先新生代的tail節點5就變成老年代的head節點

你真的瞭解Innodb儲存引擎?

 

(2)緩衝池汙染

當一個SQL查詢要掃描大量資料,導致把緩衝池中所有頁全部替換,導致大量熱資料被換出去,這就是緩衝池汙染

MySQL在老生代中新增了停留時間視窗

如果資料被讀取了並且在老身代中停留時間超過這個視窗,那麼才會被加入新生代頭部

「如何檢視這個停留時間:」

引數innodb_old_blocks_time

你真的瞭解Innodb儲存引擎?

 


「緩衝池相關引數:」

你真的瞭解Innodb儲存引擎?

 

物理層

物理層在邏輯上分為

  • 系統表空間
  • 使用者表空間
  • Redo日誌。

系統表空間裡有 ibdata 檔案和一些 Undo,ibdata 檔案裡有 insert buffer 段、double write段、回滾段、索引段、資料字典段和 Undo 資訊段。

使用者表空間是指以 .ibd 為字尾的檔案,檔案中包含 insert buffer 的 bitmap 頁、葉子頁(這裡儲存真正的使用者資料)、非葉子頁。InnoDB 表是索引組織表,採用 B+ 樹組織儲存,資料都儲存在葉子節點中,分支節點(即非葉子頁)儲存索引分支查詢的資料值。

Redo 日誌中包括多個 Redo 檔案,這些檔案迴圈使用,當達到一定儲存閾值(0.75)時會觸發checkpoint 刷髒頁操作,同時也會在 MySQL 例項異常當機後重啟,InnoDB 表資料自動還原恢復過程中使用。


你真的瞭解Innodb儲存引擎?

 

使用者讀取或者寫入的最新資料都儲存在 Buffer Pool 中

如果 Buffer Pool 中沒有找到則會讀取物理檔案進行查詢,之後儲存到 Buffer Pool 中並返回給 MySQL Server。Buffer Pool 採用LRU 機制。

Buffer Pool 決定了一個 SQL 執行的速度快慢,如果查詢結果頁都在記憶體中則返回結果速度很快,否則會產生物理讀(磁碟讀),返回結果時間變長,效能遠不如儲存在記憶體中。


「Redo 和 Undo」

Redo log 是一個迴圈複用的檔案集,負責記錄 InnoDB 中所有對 Buffer Pool的物理修改日誌,當 Redo log檔案空間中,檢查點位置的 LSN 和最新寫入的 LSN 差值(checkpoint_age)達到 Redo log 檔案總空間的 75% 後,InnoDB 會進行非同步重新整理操作,直到降至 75% 以下,並釋放 Redo log 的空間;當 checkpoint_age 達到檔案總量大小的 90% 後,會觸發同步重新整理,此時 InnoDB 處於掛起狀態無法操作。

Redo記錄變更後的資料。

Undo記錄事務資料變更前的值,用於回滾和其他事務多版本讀。


「ARIES 三原則」

ARIES 三原則,是指 Write Ahead Logging(WAL)。

先寫日誌後寫磁碟,日誌成功寫入後事務就不會丟失,後續由 checkpoint 機制來保證磁碟物理檔案與 Redo 日誌達到一致性;

利用 Redo 記錄變更後的資料,即 Redo 記錄事務資料變更後的值;

利用 Undo 記錄變更前的資料,即 Undo 記錄事務資料變更前的值,用於回滾和其他事務多版本讀。

 

===============================

我是Liusy,一個喜歡健身的程式設計師。

獲取更多幹貨以及最新訊息,請關注_公_眾_號:上古偽神

如果對您有幫助,點個關注、轉發就是對我最大的支援!!!謝謝

相關文章