上節咱們最後說到,SQL 的執行計劃是執行器組件調用存儲引擎的接口來完成的。 那咱們能夠理解爲:MySQL 這個數據庫管理系統是依靠存儲引擎與存放數據的磁盤文件進行交互的。html
那麼 MySQL 有哪些存儲引擎呢? 主要有 MyISAM、InnoDB、Memory等等。而如今互聯網中,基本都是使用 InnoDB 存儲引擎,因此接下來我將簡單總結本身關於 InnoDB 存儲引擎的學習,比較簡單的介紹 InnoDB 存儲引擎裏面的組件。數據庫
咱們如今都知道了,數據庫的數據是存放在磁盤文件中的。 那麼,咱們每次對錶的增刪改查都是直接在磁盤文件裏面操做嗎?併發
答案:不是的! 由於磁盤文件的隨機讀寫的性能是很是差的,若是全部操做都在磁盤中進行,那麼就不會有高性能 MySQL 的說法了,MySQL 也不能支持高併發,也不會在互聯網中如此的流行。高併發
這時候要引入 InnoDB 存儲引擎最重要的一個組件,就是緩衝池(Buffer Pool)
,它是一個很是重要的內存結構。它是內存裏面的,憑藉着內存很是高性能的讀寫,使得 MySQL 可以支持高併發。性能
咱們先複習一下 MySQL 接收請求的過程。 ①、MySQL 的工做線程專門監聽數據庫鏈接池的鏈接,有鏈接就獲取鏈接中的 SQL 語句。 ②、而後將 SQL 語句交給 SQL 接口
去處理,SQL 接口裏會進行下面的一系列流程。 ③、查詢解析器
將 SQL 語句解析成 MySQL 能理解的東西。 ④、接着 查詢優化器
去爲 SQL 語句制定一套最優的執行計劃。 ⑤、執行器
會根據執行計劃去調用存儲引擎的接口。學習
上面是上篇文章總結到的東西,那麼存儲引擎的接口是怎麼進行增刪改查的呢?以更新操做爲例,其餘的同理。 首先,存儲引擎會先判斷更新 SQL 對應的數據行是否在 緩衝池(Buffer Pool)
裏面。若是在的話就直接在 緩衝池(Buffer Pool)
裏更新數據而後返回;若是不在,則從磁盤文件裏讀取數據到 緩衝池(Buffer Pool)
裏,而後進行更新操做,最後再返回結果。優化
咱們都知道,在事務中,事務提交前是能夠隨時回滾對數據的更新的。那麼是依靠什麼來作的呢?spa
依靠的是 undo 日誌文件
。線程
更新數據爲例: 假如你更新某行 id=100 的數據,將字段 name 由原來的「張三」改成「李四」,那麼此時會將 "id=10" 和 「name=張三」 這兩個關鍵信息寫入 undo 日誌文件
中。 當你事務提交前須要回滾,就會從 undo 日誌文件
中找到這兩個關鍵字,而後進行更新操做的回滾。日誌
上面說到,全部的增刪改查操做實際上是在緩衝池裏面進行的,因此其實對數據的修改並無馬上落實到磁盤文件裏面。
那麼有一個問題:在緩衝池的髒數據刷回磁盤文件中前,MySQL 宕機了怎麼辦? 此時 InnoDB 存儲引擎提供了一個很是重要的組件,就是 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 日誌
恢復以前全部髒數據的更新。
原文出處:https://www.cnblogs.com/Howinfun/p/12289860.html