【大白話系列】MySQL 學習總結 之 InnoDB 存儲引擎的架構設計

如果大家對我的 【大白話系列】MySQL 學習總結系列 感興趣的話,可以點擊關注一波。

一、存儲引擎

上節我們最後說到,SQL 的執行計劃是執行器組件調用存儲引擎的接口來完成的。
那我們可以理解爲:MySQL 這個數據庫管理系統是依靠存儲引擎與存放數據的磁盤文件進行交互的。

那麼 MySQL 有哪些存儲引擎呢?
主要有 MyISAM、InnoDB、Memory等等。而現在互聯網中,基本都是使用 InnoDB 存儲引擎,所以接下來我將簡單總結自己關於 InnoDB 存儲引擎的學習,比較簡單的介紹 InnoDB 存儲引擎裏面的組件。

二、緩衝池

我們現在都知道了,數據庫的數據是存放在磁盤文件中的。
那麼,我們每次對錶的增刪改查都是直接在磁盤文件裏面操作嗎?

答案:不是的!
因爲磁盤文件的隨機讀寫的性能是非常差的,如果所有操作都在磁盤中進行,那麼就不會有高性能 MySQL 的說法了,MySQL 也不能支持高併發,也不會在互聯網中如此的流行。

這時候要引入 InnoDB 存儲引擎最重要的一個組件,就是緩衝池(Buffer Pool),它是一個非常重要的內存結構。它是內存裏面的,憑藉着內存非常高性能的讀寫,使得 MySQL 能夠支持高併發。

緩衝池(Buffer Pool) 的使用原理:

我們先複習一下 MySQL 接收請求的過程。
①、MySQL 的工作線程專門監聽數據庫連接池的連接,有連接就獲取連接中的 SQL 語句。
②、然後將 SQL 語句交給 SQL 接口 去處理,SQL 接口裏會進行下面的一系列流程。
③、查詢解析器 將 SQL 語句解析成 MySQL 能理解的東西。
④、接着 查詢優化器 去爲 SQL 語句制定一套最優的執行計劃。
⑤、執行器 會根據執行計劃去調用存儲引擎的接口。

上面是上篇文章總結到的東西,那麼存儲引擎的接口是怎麼進行增刪改查的呢?以更新操作爲例,其他的同理。
首先,存儲引擎會先判斷更新 SQL 對應的數據行是否在 緩衝池(Buffer Pool) 裏面。如果在的話就直接在 緩衝池(Buffer Pool) 裏更新數據然後返回;如果不在,則從磁盤文件裏讀取數據到 緩衝池(Buffer Pool) 裏,然後進行更新操作,最後再返回結果。

三、undo 日誌文件

我們都知道,在事務中,事務提交前是可以隨時回滾對數據的更新的。那麼是依靠什麼來做的呢?

依靠的是 undo 日誌文件

undo 日誌文件的使用原理:

更新數據爲例:
假如你更新某行 id=100 的數據,將字段 name 由原來的“張三”改爲“李四”,那麼此時會將 “id=10” 和 “name=張三” 這兩個關鍵信息寫入 undo 日誌文件中。
當你事務提交前需要回滾,就會從 undo 日誌文件 中找到這兩個關鍵字,然後進行更新操作的回滾。

四、redo log buffer

上面說到,所有的增刪改查操作其實是在緩衝池裏面進行的,所以其實對數據的修改並沒有立刻落實到磁盤文件裏面。

那麼有一個問題:在緩衝池的髒數據刷回磁盤文件中前,MySQL 宕機了怎麼辦?
此時 InnoDB 存儲引擎提供了一個非常重要的組件,就是 redo log buffer 組件.,它也是內存裏的一塊緩衝區。

redo log buffer 的使用原理:

還是以上面的更新操作爲例,當數據更新後,會記錄下數據更新的的關鍵信息,對應的就是 redo 日誌,然後寫入 redo log buffer 裏。

但是還是會有一個問題,上面說到,redo log buffer 也是在內存裏的。那當 MySQL 宕機時,由於內存裏的所有數據都會丟失,所以緩衝池的髒數據和 redo log buffer 的日誌還是會全部丟失。
這樣會造成一種情況,客戶端收到更新成功的信息了,但是最後數據庫裏頭的數據還是沒更新成功。

所以,redo log buffer 還有一個刷盤策略,它由參數 innodb_flush_log_at_trx_commit 來控制。通常我們將此參數的值設置爲 1:​即當事務提交時,會將 redo log buffer 裏的 redo 日誌 強制刷回到磁盤中。這樣就不用擔心,事務提交成功,但是更新數據可能會丟失的問題了。即使在 緩衝池(Buffer Pool) 的髒數據刷回磁盤前, MySQL 宕機了,也不會丟失數據,因爲 MySQL 重啓時可以根據磁盤中的 redo 日誌 恢復之前所有髒數據的更新。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章