首頁 >資料庫 >mysql教程 >完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

WBOY
WBOY轉載
2022-01-19 18:03:372024瀏覽

這篇文章為大家帶來了關於mysql原理中InnoDB儲存引擎架構設計的相關知識,希望對大家有幫助。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

InnoDB元件結構:

  1. buffer pool : 緩衝池,快取磁碟的資料

  2. redo log buffer :記錄對緩衝池的操作,根據策略寫入磁碟防止宕機但交易已經提交而丟失資料

  3. undo log :當對緩衝池的數據進行修改時,在交易未提交的時候都可以進行回滾,將舊值寫入undo 日誌檔案便於回滾,此時緩衝池的資料與磁碟中的不一致,是髒資料

1. Buffer Pool

假設現在有一條更新語句:

update users set name = 'lisi' where id = 1

需要更新到資料庫,InnoDB會執行哪些動作呢?

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

首先,InnoDB會判讀緩衝池裡是否存在id = 1 這條數據,如果不存在則從磁碟載入到緩衝池中,而且還會對這行資料加獨佔鎖,防止多個sql同時修改這行資料。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

2. undo 日誌檔

#假設id = 1 這條資料name原來的值name = 'zhangsan',現在我們要更新為name = 'lisi' , 那麼我們就需要把舊值name='zhangsan'和id=1這些資訊寫入到undo日誌檔案中。

對於熟悉資料庫的同學來說都了解事務的概念,在事務未提交之前,所有操作都有可能進行回滾,即可以把name = 'lisi' 回滾到name = 'zhangsan' ,所以將更新前的值寫到undo日誌檔。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

3. 更新buffer pool 資料

在undo日誌檔案寫入完畢之後,便開始更新記憶體中的這條數據。把 id = 1 的 name = 'zhangsan' 更新為 name = 'lisi'。這時記憶體中的資料已經更新完畢,但磁碟上的還沒有變化,此時出現了不一致的髒資料。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

這時可能有一個疑問,萬一事務提交完成,但MySQL服務宕機了,而記憶體中的資料還沒寫入到磁碟,是不是會造成資料遺失而造成sql執行資料前後不一致?

4. redo log buffer

在InnoDB結構中,有一個redo log buffer 緩衝區存放redo日誌,所謂redo日誌,例如把id=1,name ='zhangsan'修改為name='lisi' 就是一條日誌。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

但此時redo log buffer 還只是存在記憶體中,沒能實現MySQL宕機後的資料復原。

5. 交易沒提交,資料庫當機後有影響嗎?

其實並沒有影響,事務沒有提交,意味著執行沒有成功,就算MySQL崩潰或宕機後,記憶體中的buffer pool 和redo log buffer 修改過的資料都會遺失,也併不影響數據前後的一致性。如果交易提交失敗,那麼資料庫的資料更加不會改變。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

6. 提交事務,redo日誌的設定策略

在提交交易時,redo日記會根據策略實作把redo日誌從redo log buffer 裡寫入磁碟。策略透過 innoDB_flush_log_at_trx_commit 來設定。

  1. innoDB_flush_log_at_trx_commit的參數為0,就算交易提交後,也不會把redo日誌寫入磁碟。 MySQL宕機後會記憶體中的資料會遺失。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

  1. innoDB_flush_log_at_trx_commit的參數為1,交易提交後,redo日誌會從記憶體刷入磁碟,只要交易提交成功,redo log 就必然存在磁碟裡。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

此時就算buffer pool 的資料沒有刷進磁碟,也可以從redo log 得知修改過哪些數據,MySQL宕機重啟後,可以從redo日誌中復原修改的資料。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

  1. innoDB_flush_log_at_trx_commit的參數為2,交易提交後,redo log 僅僅停留在 os cache 中,還沒刷進磁碟,萬一此時服務宕機了。那麼os cache 中的資料也會遺失,即使交易提交成功,也會造成資料遺失。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

看完這幾種相信為了確保資料安全,參數為1是最佳策略。

7. 事務的最終提交,binlog

binlog其實是屬於MySQL Server 的日誌文件,而在這裡提出是因為與redo log有著很大的關聯。

1) biglog 與redo log的區別

  • redo log:記錄的是偏物理性質重做日誌,例如「對哪個資料頁中的什麼記錄,做了哪些修改”

  • binlog:偏向邏輯性的日誌,如:「對users表中的id=10的一行資料做了更新操作,更新以後的值是什麼」

2) 提交交易的時候同時寫入binlog

在執行更新的同時,innoDB與執行器一直在交互,包括載入資料到緩衝池,寫入undo日誌文件,更新記憶體數據,寫redo日誌和刷入磁碟等。而對binlog的寫入也是由執行器執行。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

其中 1、2、3、4步驟為執行更新語句所做的事,而 5、6是提交交易開始做的事。

3) binlog日誌刷盤策略分析

sync_binlog參數控制binlog的刷盤策略

  1. sync_ binlog預設值是0,提交交易後,會把binlog日誌存在os cache 中,MySQL宕機後會造成os cache中資料的遺失

  2. sync_binlog 值為1,提交交易後,把binlog日誌直接刷入磁碟中。

4) 基於binlog 和redo log 完成事務的提交

binlog寫入磁碟後,會把binlog日誌檔案所在的位置和檔案名稱都寫入redo log日誌檔中,同時在redo log日誌檔裡寫入一個commit標記。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

5) commit 標記有什麼意義?

commit 標記意義著保持redo log 和 binlog 日誌一致。如果在步驟5或步驟6,事務提交開始,MySQL宕機了,redo log 中並沒有commit標記,都算事務提交失敗。

意味著 commint 標記是交易最終提交成功。

8. buffer pool 髒資料刷入磁碟

髒資料刷入磁碟是由後台IO執行緒隨機刷入磁碟的。

完全掌握MySQL原理篇之InnoDB儲存引擎架構設計

這時候考慮到,在刷入磁碟之前,MySQL宕機怎麼辦?這時候,事務已經提交成功,redo log 中也有commit標記,就算宕機了,重啟後,也會根據redo日誌檔把資料更新到記憶體中,等待IO線程的刷盤。

9. 總結

透過更新語句執行分析之後,了解到InnoDB儲存引擎中包含了buffer pool 緩衝池、redo log buffer 緩衝區等快取數據, undo、reod log等日誌文件,同時也有MySQL Server 的日誌檔。

在執行更新語句的時候,會修改buffer pool、寫undo日誌檔案、 寫redo log buffer等操作;提交交易時,會將redo log 刷盤,binlog刷盤,寫入binlog檔名稱和位置,寫入commit標記,最後等待IO線程將buffer pool的髒數據隨機刷盤。

推薦學習:mysql影片教學

#

以上是完全掌握MySQL原理篇之InnoDB儲存引擎架構設計的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除