一、存儲引擎
上節(jié)我們最后說到,SQL 的執(zhí)行計劃是執(zhí)行器組件調(diào)用存儲引擎的接口來完成的。
那我們可以理解為:MySQL 這個數(shù)據(jù)庫管理系統(tǒng)是依靠存儲引擎與存放數(shù)據(jù)的磁盤文件進(jìn)行交互的。
那么 MySQL 有哪些存儲引擎呢?
主要有 MyISAM、InnoDB、Memory等等。而現(xiàn)在互聯(lián)網(wǎng)中,基本都是使用 InnoDB 存儲引擎,所以接下來我將簡單總結(jié)自己關(guān)于 InnoDB 存儲引擎的學(xué)習(xí),比較簡單的介紹 InnoDB 存儲引擎里面的組件。
二、緩沖池
我們現(xiàn)在都知道了,數(shù)據(jù)庫的數(shù)據(jù)是存放在磁盤文件中的。
那么,我們每次對表的增刪改查都是直接在磁盤文件里面操作嗎?
答案:不是的!
因為磁盤文件的隨機(jī)讀寫的性能是非常差的,如果所有操作都在磁盤中進(jìn)行,那么就不會有高性能 MySQL 的說法了,MySQL 也不能支持高并發(fā),也不會在互聯(lián)網(wǎng)中如此的流行。
這時候要引入 InnoDB 存儲引擎最重要的一個組件,就是緩沖池(Buffer Pool)
,它是一個非常重要的內(nèi)存結(jié)構(gòu)。它是內(nèi)存里面的,憑借著內(nèi)存非常高性能的讀寫,使得 MySQL 能夠支持高并發(fā)。
緩沖池(Buffer Pool) 的使用原理:
我們先復(fù)習(xí)一下 MySQL 接收請求的過程。
①、MySQL 的工作線程專門監(jiān)聽數(shù)據(jù)庫連接池的連接,有連接就獲取連接中的 SQL 語句。
②、然后將 SQL 語句交給 SQL 接口
去處理,SQL 接口里會進(jìn)行下面的一系列流程。
③、查詢解析器
將 SQL 語句解析成 MySQL 能理解的東西。
④、接著 查詢優(yōu)化器
去為 SQL 語句制定一套最優(yōu)的執(zhí)行計劃。
⑤、執(zhí)行器
會根據(jù)執(zhí)行計劃去調(diào)用存儲引擎的接口。
上面是上篇文章總結(jié)到的東西,那么存儲引擎的接口是怎么進(jìn)行增刪改查的呢?以更新操作為例,其他的同理。
首先,存儲引擎會先判斷更新 SQL 對應(yīng)的數(shù)據(jù)行是否在 緩沖池(Buffer Pool)
里面。如果在的話就直接在 緩沖池(Buffer Pool)
里更新數(shù)據(jù)然后返回;如果不在,則從磁盤文件里讀取數(shù)據(jù)到 緩沖池(Buffer Pool)
里,然后進(jìn)行更新操作,最后再返回結(jié)果。
三、undo 日志文件
我們都知道,在事務(wù)中,事務(wù)提交前是可以隨時回滾對數(shù)據(jù)的更新的。那么是依靠什么來做的呢?
依靠的是 undo 日志文件
。
undo 日志文件的使用原理:
更新數(shù)據(jù)為例:
假如你更新某行 id=100 的數(shù)據(jù),將字段 name 由原來的“張三”改為“李四”,那么此時會將 "id=10" 和 “name=張三” 這兩個關(guān)鍵信息寫入 undo 日志文件
中。
當(dāng)你事務(wù)提交前需要回滾,就會從 undo 日志文件
中找到這兩個關(guān)鍵字,然后進(jìn)行更新操作的回滾。
四、redo log buffer
上面說到,所有的增刪改查操作其實是在緩沖池里面進(jìn)行的,所以其實對數(shù)據(jù)的修改并沒有立刻落實到磁盤文件里面。
那么有一個問題:在緩沖池的臟數(shù)據(jù)刷回磁盤文件中前,MySQL 宕機(jī)了怎么辦?
此時 InnoDB 存儲引擎提供了一個非常重要的組件,就是 redo log buffer
組件.,它也是內(nèi)存里的一塊緩沖區(qū)。
redo log buffer 的使用原理:
還是以上面的更新操作為例,當(dāng)數(shù)據(jù)更新后,會記錄下數(shù)據(jù)更新的的關(guān)鍵信息,對應(yīng)的就是 redo 日志,然后寫入 redo log buffer
里。
但是還是會有一個問題,上面說到,redo log buffer
也是在內(nèi)存里的。那當(dāng) MySQL 宕機(jī)時,由于內(nèi)存里的所有數(shù)據(jù)都會丟失,所以緩沖池的臟數(shù)據(jù)和 redo log buffer
的日志還是會全部丟失。
這樣會造成一種情況,客戶端收到更新成功的信息了,但是最后數(shù)據(jù)庫里頭的數(shù)據(jù)還是沒更新成功。
所以,redo log buffer
還有一個刷盤策略。正常是,當(dāng)事務(wù)提交時,會將 redo log buffer
里的 redo 日志
刷回到磁盤中,這樣就不用擔(dān)心,事務(wù)提交成功,但是更新數(shù)據(jù)可能會丟失的問題了。即使在 緩沖池(Buffer Pool)
的臟數(shù)據(jù)刷回磁盤前, MySQL 宕機(jī)了,也不會丟失數(shù)據(jù),因為 MySQL 重啟時可以根據(jù)磁盤中的 redo 日志
恢復(fù)之前所有臟數(shù)據(jù)的更新。
總結(jié)
以上所述是小編給大家介紹的MySQL 學(xué)習(xí)總結(jié) 之 初步了解 InnoDB 存儲引擎的架構(gòu)設(shè)計,希望對大家有所幫助!
您可能感興趣的文章:- mysql字符集和數(shù)據(jù)庫引擎修改方法分享
- MySQL修改字符集的實戰(zhàn)教程
- MySQL查看與修改字符集的方法實例教程
- mysql 啟動1067錯誤及修改字符集重啟之后復(fù)原無效問題
- Linux下MySQL 5.5/5.6的修改字符集編碼為UTF8的方法
- Mysql數(shù)據(jù)庫支持的存儲引擎對比
- 基于 Mysql 實現(xiàn)一個簡易版搜索引擎
- Mysql中存儲引擎的區(qū)別及比較
- MySQL修改默認(rèn)引擎和字符集詳情