初探InnoDB存儲(chǔ)引擎的架構(gòu)設(shè)計(jì)

前言

InnoDB組件結(jié)構(gòu):

  1. buffer pool : 緩沖池榜田,緩存磁盤(pán)的數(shù)據(jù)
  2. redo log buffer :記錄對(duì)緩沖池的操作源请,根據(jù)策略寫(xiě)入磁盤(pán)防止宕機(jī)但事務(wù)已經(jīng)提交而丟失數(shù)據(jù)
  3. undo log :當(dāng)對(duì)緩沖池的數(shù)據(jù)進(jìn)行修改時(shí),在事務(wù)未提交的時(shí)候都可以進(jìn)行回滾挽铁,將舊值寫(xiě)入 undo 日志文件便于回滾诫硕,此時(shí)緩沖池的數(shù)據(jù)與磁盤(pán)中的不一致雕蔽,是臟數(shù)據(jù)

1. Buffer Pool

假設(shè)現(xiàn)在有一條更新語(yǔ)句:

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

需要更新到數(shù)據(jù)庫(kù),InnoDB會(huì)執(zhí)行哪些操作呢讳苦?

圖 1

首先带膜,InnoDB會(huì)判讀緩沖池里是否存在 id = 1 這條數(shù)據(jù),如果不存在則從磁盤(pán)中加載到緩沖池中鸳谜,而且還會(huì)對(duì)這行數(shù)據(jù)加獨(dú)占鎖膝藕,防止多個(gè)sql同時(shí)修改這行數(shù)據(jù)。

圖 2

2. undo 日志文件

假設(shè) id = 1 這條數(shù)據(jù)name原來(lái)的值 name = 'zhangsan'咐扭,現(xiàn)在我們要更新為 name = 'lisi' , 那么我們就需要把舊值name='zhangsan'和id=1這些信息寫(xiě)入到undo日志文件中芭挽。

對(duì)于熟悉數(shù)據(jù)庫(kù)的同學(xué)來(lái)說(shuō)都了解事務(wù)的概念,在事務(wù)未提交之前蝗肪,所有操作都有可能進(jìn)行回滾袜爪,即可以把 name = 'lisi' 回滾到 name = 'zhangsan',所以將更新前的值寫(xiě)到undo日志文件薛闪。

圖 3

3. 更新buffer pool 數(shù)據(jù)

在undo日志文件寫(xiě)入完畢之后辛馆,便開(kāi)始更新內(nèi)存中的這條數(shù)據(jù)。把 id = 1 的 name = 'zhangsan' 更新為 name = 'lisi'豁延。這時(shí)內(nèi)存中的數(shù)據(jù)已經(jīng)更新完畢昙篙,但磁盤(pán)上的還沒(méi)有變化,此時(shí)出現(xiàn)了不一致的臟數(shù)據(jù)诱咏。

圖 4

這時(shí)可能有一個(gè)疑問(wèn)苔可,萬(wàn)一事務(wù)提交完成,但MySQL服務(wù)宕機(jī)了袋狞,而內(nèi)存中的數(shù)據(jù)還沒(méi)寫(xiě)入到磁盤(pán)硕蛹,是不是會(huì)造成數(shù)據(jù)丟失而造成sql執(zhí)行數(shù)據(jù)前后不一致醇疼?

4. redo log buffer

在InnoDB結(jié)構(gòu)中,有一個(gè) redo log buffer 緩沖區(qū)存放redo日志法焰,所謂redo日志秧荆,例如 把id=1,name='zhangsan'修改為name='lisi' 便是一條日志埃仪。

圖 5

但這時(shí)redo log buffer 還僅僅存在內(nèi)存中乙濒,沒(méi)能實(shí)現(xiàn)MySQL宕機(jī)后的數(shù)據(jù)恢復(fù)。

5. 事務(wù)沒(méi)提交卵蛉,數(shù)據(jù)庫(kù)宕機(jī)后有影響嗎颁股?

其實(shí)并沒(méi)有影響,事務(wù)沒(méi)有提交傻丝,意味著執(zhí)行沒(méi)有成功甘有,就算MySQL崩潰或者宕機(jī)后,內(nèi)存中的 buffer pool 和 redo log buffer 修改過(guò)的數(shù)據(jù)都會(huì)丟失葡缰,也并不影響數(shù)據(jù)前后的一致性亏掀。
如果事務(wù)提交失敗,那數(shù)據(jù)庫(kù)的數(shù)據(jù)更加不會(huì)改變泛释。

圖 6

6. 提交事務(wù)滤愕,redo日志的配置策略

在提交事務(wù)時(shí),redo日記會(huì)根據(jù)策略實(shí)現(xiàn)把redo日志從 redo log buffer 里寫(xiě)入磁盤(pán)怜校。策略通過(guò) innoDB_flush_log_at_trx_commit 來(lái)配置间影。

  1. innoDB_flush_log_at_trx_commit的參數(shù)為0,就算事務(wù)提交后茄茁,也不會(huì)把redo日志寫(xiě)入磁盤(pán)魂贬。MySQL宕機(jī)后會(huì)內(nèi)存中的數(shù)據(jù)會(huì)丟失。
圖 7
  1. innoDB_flush_log_at_trx_commit的參數(shù)為1裙顽,事務(wù)提交后随橘,redo日志會(huì)從內(nèi)存刷入磁盤(pán),只要事務(wù)提交成功锦庸,redo log 就必然存在磁盤(pán)里机蔗。
圖 8

此時(shí)就算buffer pool 的數(shù)據(jù)沒(méi)有刷進(jìn)磁盤(pán),也可以從redo log 中得知修改過(guò)哪些數(shù)據(jù)甘萧,MySQL宕機(jī)重啟后萝嘁,可以從redo日志中恢復(fù)修改的數(shù)據(jù)。

圖 9
  1. innoDB_flush_log_at_trx_commit的參數(shù)為2扬卷,事務(wù)提交后牙言,redo log 僅僅停留在 os cache 中,還沒(méi)刷進(jìn)磁盤(pán)怪得,萬(wàn)一此時(shí)服務(wù)宕機(jī)了咱枉。那么os cache 中的數(shù)據(jù)也會(huì)丟失卑硫,即使事務(wù)提交成功,也會(huì)造成數(shù)據(jù)丟失蚕断。
圖 10

看完這幾種相信為了保證數(shù)據(jù)安全欢伏,參數(shù)為1是最佳策略。

7. 事務(wù)的最終提交亿乳,binlog

binlog其實(shí)是屬于MySQL Server 的日志文件硝拧,而在這出提出是因?yàn)榕credo log有著很大的關(guān)聯(lián)。

1) biglog 與 redo log的區(qū)別

  • redo log:記錄的是偏物理性質(zhì)重做日志葛假,比如 “對(duì)哪個(gè)數(shù)據(jù)頁(yè)中的什么記錄障陶,做了哪些修改”
  • binlog:偏向于邏輯性的日志,如:“對(duì)users表中的id=10的一行數(shù)據(jù)做了更新操作聊训,更新以后的值是什么”

2) 提交事務(wù)的時(shí)候同時(shí)寫(xiě)入binlog

在執(zhí)行更新的同時(shí)抱究,innoDB與執(zhí)行器一直在交互,包括加載數(shù)據(jù)到緩沖池带斑,寫(xiě)入undo日志文件鼓寺,更新內(nèi)存數(shù)據(jù),寫(xiě)redo日志和刷入磁盤(pán)等遏暴。而對(duì)binlog的寫(xiě)入也是由執(zhí)行器執(zhí)行。

圖 11

其中 1指黎、2朋凉、3、4步驟為執(zhí)行更新語(yǔ)句做的事醋安,而 5杂彭、6是提交事務(wù)開(kāi)始做的事。

3) binlog日志刷盤(pán)策略分析

sync_binlog參數(shù)控制binlog的刷盤(pán)策略

  1. sync_ binlog默認(rèn)值是0吓揪,提交事務(wù)后亲怠,會(huì)把binlog日志存在 os cache 中,MySQL宕機(jī)后會(huì)造成os cache中數(shù)據(jù)的丟失
  2. sync_binlog 值為1柠辞,提交事務(wù)后团秽,把binlog日志直接刷入磁盤(pán)中。

4) 基于binlog 和 redo log 完成事務(wù)的提交

binlog寫(xiě)入磁盤(pán)后叭首,會(huì)把binlog日志文件所在的位置和文件名稱都寫(xiě)入redo log日志文件中习勤,同時(shí)在redo log日志文件里寫(xiě)入一個(gè)commit標(biāo)記。

圖 12

5) commit 標(biāo)記有什么意義焙格?

commit 標(biāo)記意義著保持redo log 和 binlog 日志一致图毕。
如果在步驟5或者步驟6,事務(wù)提交開(kāi)始眷唉,MySQL宕機(jī)了予颤,redo log 中并沒(méi)有commit標(biāo)記囤官,都算事務(wù)提交失敗。

意味著 commint 標(biāo)記是事務(wù)最終提交成功蛤虐。

8. buffer pool 臟數(shù)據(jù)刷入磁盤(pán)

臟數(shù)據(jù)刷入磁盤(pán)是由后臺(tái)IO線程隨機(jī)刷入磁盤(pán)的党饮。

圖 13

這時(shí)候考慮到,在刷入磁盤(pán)之前笆焰,MySQL宕機(jī)怎么辦劫谅?這時(shí)候,事務(wù)已經(jīng)提交成功嚷掠,redo log 中也有commit標(biāo)記捏检,就算宕機(jī)了,重啟后不皆,也會(huì)根據(jù)redo日志文件把數(shù)據(jù)更新到內(nèi)存中贯城,等待IO線程的刷盤(pán)。

9. 總結(jié)

通過(guò)更新語(yǔ)句執(zhí)行分析之后霹娄,了解到InnoDB存儲(chǔ)引擎中包含了 buffer pool 緩沖池能犯、redo log buffer 緩沖區(qū)等緩存數(shù)據(jù),undo犬耻、reod log等日志文件踩晶,同時(shí)也有MySQL Server 的日志文件。

在執(zhí)行更新語(yǔ)句的時(shí)候枕磁,會(huì)修改buffer pool渡蜻、寫(xiě)undo日志文件、 寫(xiě)redo log buffer等操作计济;提交事務(wù)時(shí)茸苇,會(huì)將redo log 刷盤(pán),binlog刷盤(pán)沦寂,寫(xiě)入binlog文件名稱和位置学密,寫(xiě)入commit標(biāo)記,最后等待IO線程將buffer pool的臟數(shù)據(jù)隨機(jī)刷盤(pán)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載传藏,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者腻暮。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市毯侦,隨后出現(xiàn)的幾起案子西壮,更是在濱河造成了極大的恐慌,老刑警劉巖叫惊,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件款青,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡霍狰,警方通過(guò)查閱死者的電腦和手機(jī)抡草,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)饰及,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人康震,你說(shuō)我怎么就攤上這事燎含。” “怎么了腿短?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵屏箍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我橘忱,道長(zhǎng)赴魁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任钝诚,我火速辦了婚禮颖御,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凝颇。我一直安慰自己潘拱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拧略。 她就那樣靜靜地躺著芦岂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垫蛆。 梳的紋絲不亂的頭發(fā)上禽最,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音月褥,去河邊找鬼弛随。 笑死瓢喉,一個(gè)胖子當(dāng)著我的面吹牛宁赤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播栓票,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼决左,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了走贪?” 一聲冷哼從身側(cè)響起佛猛,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坠狡,沒(méi)想到半個(gè)月后继找,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逃沿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年婴渡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幻锁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡边臼,死狀恐怖哄尔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柠并,我是刑警寧澤岭接,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站臼予,受9級(jí)特大地震影響鸣戴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘟栖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一葵擎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧半哟,春花似錦酬滤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至戒良,卻和暖如春体捏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糯崎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工几缭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沃呢。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓年栓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親薄霜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子某抓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容