【大白話系列】MySQL 學習總結 之 初步瞭解 InnoDB 儲存引擎的架構設計
一、儲存引擎
上節我們最後說到,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
還有一個刷盤策略。正常是,當事務提交時,會將 redo log buffer
裡的 redo 日誌
刷回到磁碟中,這樣就不用擔心,事務提交成功,但是更新資料可能會丟失的問題了。即使在 緩衝池(Buffer Pool)
的髒資料刷回磁碟前, MySQL 宕機了,也不會丟失資料,因為 MySQL 重啟時可以根據磁碟中的 redo 日誌
恢復之前所有髒資料的更新