溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

發(fā)布時(shí)間:2022-01-20 09:58:21 來(lái)源:億速云 閱讀:159 作者:小新 欄目:MySQL數(shù)據(jù)庫(kù)

這篇文章主要介紹MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

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í)行哪些操作呢?

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

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

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

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日志文件。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

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ù)。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

這時(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' 便是一條日志。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

但這時(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ì)改變。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

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ì)丟失。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

  1. innoDB_flush_log_at_trx_commit的參數(shù)為1,事務(wù)提交后,redo日志會(huì)從內(nèi)存刷入磁盤(pán),只要事務(wù)提交成功,redo log 就必然存在磁盤(pán)里。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

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

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

  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ù)丟失。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

看完這幾種相信為了保證數(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í)行。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

其中 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日志文件所在的位置和文件名稱(chēng)都寫(xiě)入redo log日志文件中,同時(shí)在redo log日志文件里寫(xiě)入一個(gè)commit標(biāo)記。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

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)的。

MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析

這時(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)。

以上是“MySQL中InnoDB存儲(chǔ)引擎架構(gòu)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI