最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql數(shù)據(jù)庫(kù)面試必備之三大log介紹

 更新時(shí)間:2021年12月16日 09:39:32   作者:西瓜味兒的小志  
大家好,本篇文章主要講的是Mysql數(shù)據(jù)庫(kù)面試必備之三大log介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下

快,開篇大伙先思考一個(gè)問(wèn)題,MySQL 是怎么保證數(shù)據(jù)不丟失的呢?

其實(shí)要保證數(shù)據(jù)不丟失,說(shuō)白了要具有下面兩種能力:
(1)能恢復(fù)到任何時(shí)間點(diǎn)的狀態(tài);
(2)能保證 MySQL 在任何時(shí)間段突然宕機(jī)重啟,已提交的數(shù)據(jù)不會(huì)丟失,未提交完整的數(shù)據(jù)也會(huì)自動(dòng)回滾;

這不就引出來(lái)今天要聊的主題了么,實(shí)現(xiàn)第一點(diǎn)需要用 bin log,實(shí)現(xiàn)第二點(diǎn)需要用 redo log 和 undo log。

了解三大log之前,我們先看一下Mysql數(shù)據(jù)更新的流程:

在這里插入圖片描述

上面這張圖包含了 redo log、bin log、undo log 三種日志之間的大致關(guān)系,下面進(jìn)入正題。

一、redo log 重做日志(MySQL 存儲(chǔ)引擎 InnoDB 的事務(wù)日志)

我們知道 MySQL 數(shù)據(jù)存在磁盤中,每次讀寫數(shù)據(jù)需做磁盤 IO,并發(fā)場(chǎng)景下性能差。為此 MySQL 引入緩存 Buffer Pool 做優(yōu)化。其包含磁盤中部分?jǐn)?shù)據(jù)頁(yè)(page)的映射,來(lái)緩解數(shù)據(jù)庫(kù)的磁盤壓力。

當(dāng)從數(shù)據(jù)庫(kù)讀數(shù)據(jù)時(shí),首先從緩存中讀,緩存中沒(méi)有,則從磁盤讀后放入緩存;當(dāng)向數(shù)據(jù)庫(kù)寫數(shù)據(jù)時(shí),先向緩存中寫,此時(shí)緩存中的數(shù)據(jù)頁(yè)數(shù)據(jù)會(huì)變更,該數(shù)據(jù)頁(yè)叫臟頁(yè),Buffer Pool 中修改完數(shù)據(jù)后會(huì)按照設(shè)定的策略再定期刷到磁盤中去,這個(gè)過(guò)程叫刷臟頁(yè)。

那么問(wèn)題來(lái)了,如果 Buffer Pool 中修改的數(shù)據(jù)還沒(méi)有及時(shí)的刷到磁盤,MySQL 宕機(jī)重啟,就會(huì)導(dǎo)致數(shù)據(jù)丟失,無(wú)法保證事務(wù)的持久性,怎么辦?

redo log 解決了這個(gè)問(wèn)題。就是說(shuō)數(shù)據(jù)庫(kù)在修改數(shù)據(jù)時(shí),會(huì)把更新記錄先寫到 redo log 中,再去修改 Buffer Pool 中的數(shù)據(jù),當(dāng)提交事務(wù)時(shí),調(diào)用 fsync 把 redo log 刷入磁盤。至于緩存中更新的數(shù)據(jù)文件何時(shí)刷入磁盤,則由后臺(tái)線程異步處理。

注意:此時(shí) redo log 的事務(wù)狀態(tài)是 prepare,還未真正提交成功,要等 bin log 日志寫入磁盤完成后才會(huì)變?yōu)?commit,事務(wù)才算真正提交成功。

redo log 的寫入方式?

redo log 采用大小固定,循環(huán)寫入的方式,當(dāng)寫滿后,會(huì)重新從頭開始循環(huán)寫,類似一個(gè)環(huán)狀。這樣設(shè)計(jì)原因是 redo log 記錄的是數(shù)據(jù)頁(yè)上的修改,如果 Buffer Pool 中數(shù)據(jù)頁(yè)已經(jīng)刷到磁盤,這些記錄就失效了,新日志會(huì)將這些失效的記錄覆蓋擦除。

注意:redo log 滿了,在擦除之前,要確保這些要被擦除記錄都已經(jīng)刷到磁盤中了。在擦除舊記錄釋放新空間期間,不能再接收新的更新請(qǐng)求,此時(shí) MySQL 性能會(huì)下降。因此高并發(fā)情況下,合理調(diào)整 redo log 大小很重要。

crash-safe 能力是什么?

Innodb 引擎有 crash-safe 能力,即事務(wù)提交過(guò)程中任何階段,MySQL 宕機(jī)重啟后都能保證事務(wù)的完整性,已提交的數(shù)據(jù)不會(huì)丟失。這種能力是通過(guò)redo log保證的,MySQL 宕機(jī)重啟,系統(tǒng)將自動(dòng)檢查 redo log,將修改還未寫入磁盤的數(shù)據(jù)從 redo log 恢復(fù)到 MySQL 中。

二、undo log 回滾日志(MySQL 存儲(chǔ)引擎 InnoDB 的事務(wù)日志)

undo log 記錄的是數(shù)據(jù)修改之前的狀態(tài),屬于邏輯日志,起到回滾的作用,是保證事務(wù)原子性的關(guān)鍵。
舉個(gè)栗子:假如更新 ID=1 記錄的 name 字段,name 原始數(shù)據(jù)為小王,現(xiàn)改 name 為小張,事務(wù)執(zhí)行 update X set name = 小張 where id =1 語(yǔ)句時(shí),先在 undo log 中記錄一條相反邏輯的 update X set name = 小王 where id =1 記錄,這樣當(dāng)某些原因?qū)е率聞?wù)失敗,就可借助 undo log 將數(shù)據(jù)回滾到事務(wù)執(zhí)行前的狀態(tài)。

那么問(wèn)題來(lái)了:同一個(gè)事務(wù)的一條記錄被多次修改,難道每次都要把數(shù)據(jù)修改前的狀態(tài)寫 undo log 嗎?

不會(huì),因?yàn)?undo log 只記錄事務(wù)開始前數(shù)據(jù)的原始版本,當(dāng)再次對(duì)這行數(shù)據(jù)修改時(shí),產(chǎn)生的修改記錄會(huì)寫到 redo log。undo log 負(fù)責(zé)回滾,redo log負(fù)責(zé)前滾。

啥是回滾和前滾?

(1)回滾

未提交的事務(wù),即事務(wù)未執(zhí)行 commit。但事務(wù)內(nèi)修改的臟頁(yè)中,有一部分已刷盤。此時(shí)數(shù)據(jù)庫(kù)宕機(jī)重啟,需要回滾來(lái)將先前那部分已經(jīng)刷盤的臟塊從磁盤上撤銷。

(2)前滾

未完全提交的事務(wù),即事務(wù)已經(jīng)執(zhí)行 commit,但該事務(wù)內(nèi)修改的臟頁(yè)中只有一部分?jǐn)?shù)據(jù)被刷盤,另一部分還在 buffer pool,此時(shí)數(shù)據(jù)庫(kù)宕機(jī)重啟,就要用前滾來(lái)將未來(lái)得及刷盤的數(shù)據(jù)從 redo log 中恢復(fù)出來(lái)并刷盤。?

三、bin log 歸檔日志(數(shù)據(jù)庫(kù) Server 層二進(jìn)制邏輯日志、和什么引擎無(wú)關(guān))

bin log 記錄了用戶對(duì)數(shù)據(jù)庫(kù)所有 sql 操作(不包含查詢語(yǔ)句,因?yàn)檫@類操作對(duì)數(shù)據(jù)本身沒(méi)有修改)。之所以可以稱為歸檔日志,是因?yàn)樗粫?huì)像 redo log 那樣循環(huán)擦除之前的記錄,而是會(huì)一直記錄日志。一個(gè) bin log 文件默認(rèn)最大容量1G(可通過(guò) max_binlog_size 參數(shù)修改),單個(gè)日志超過(guò)最大值則會(huì)新創(chuàng)建一個(gè)文件繼續(xù)寫。
注意:日志可能是基于事務(wù)來(lái)記錄的,而事務(wù)不應(yīng)該跨文件記錄,如果 binlog 日志文件達(dá)到了最大值但剛好事務(wù)還沒(méi)有提交,此時(shí)則不會(huì)創(chuàng)建新文件記錄,而是繼續(xù)增大日志。因此 max_binlog_size 的值和實(shí)際的 binlog 文件大小不一定相等。

經(jīng)過(guò)上述介紹,binlog 主要用就是主從同步和數(shù)據(jù)庫(kù)基于時(shí)間點(diǎn)的還原

那么問(wèn)題來(lái)了,可以沒(méi)有 binlog 嗎(有了 redo log 為啥還需要 bin log)?

需要分場(chǎng)景來(lái)看:

主從模式下,binlog 是必須的,因?yàn)閺膸?kù)的數(shù)據(jù)同步需要依賴 binlog;

單機(jī)模式下,不考慮數(shù)據(jù)庫(kù)基于時(shí)間點(diǎn)的還原,binlog 就不是必須的,因?yàn)橛?redo log 就可以保證 crash-safe 能力了;

redo log 的記錄修改落盤后,日志會(huì)被覆蓋掉,無(wú)法用于數(shù)據(jù)恢復(fù)等操作,redo log 是 innodb 引擎層實(shí)現(xiàn)的,并不是所有引擎都有;

redo log 與 bin log 的區(qū)別?

在這里插入圖片描述

?什么是 redo log 兩階段提交,為什么要這么做?
更新內(nèi)存后引擎層寫 redo log 將狀態(tài)改成 prepare 為提交第一階段,Server 層寫 bin log,將狀態(tài)改成 commit 為提交第二階段。 兩階段提交目的是確保 binl og 和 redo log 數(shù)據(jù)一致性。

如果不是兩階段提交可能會(huì)出現(xiàn)什么情況?
1)假設(shè)先寫 redo log 再寫 bin log,即 redo log 沒(méi)有 prepare 階段,寫完直接置為commit,然后再寫 bin log。如果寫完 redo log 后還沒(méi)寫完 bin log 數(shù)據(jù)庫(kù)宕機(jī)了,重啟后系統(tǒng)自動(dòng)用 redo log 恢復(fù),此時(shí)會(huì)造成磁盤上數(shù)據(jù)頁(yè)數(shù)據(jù)比 bin log 上的記錄數(shù)據(jù)多,數(shù)據(jù)不一致。
2)假設(shè)先寫 bin log 再寫 redo log,如果寫完 bin log 沒(méi)寫完 redo log 數(shù)據(jù)庫(kù)宕機(jī)了,那么 bin log 上的記錄就會(huì)比磁盤上數(shù)據(jù)頁(yè)的記錄多一些,下次用 bin log 恢復(fù)數(shù)據(jù),恢復(fù)后的數(shù)據(jù)和原來(lái)的數(shù)據(jù)不一致。

描述一下 redo log 容災(zāi)恢復(fù)過(guò)程?
如果 redo log 是完整(commit 狀態(tài))的,直接用 redo log 恢復(fù);
如果 redo log 是預(yù)提交 prepare 但不是 commit 狀態(tài),此時(shí)要去判斷 binlog 是否完整,如果完整(commit)那就提交 redo log,再用 redo log 恢復(fù),不完整就回滾事務(wù)。

?到此這篇關(guān)于Mysql數(shù)據(jù)庫(kù)面試必備之三大log介紹的文章就介紹到這了,更多相關(guān)Mysql三大log內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

阿克苏市| 垦利县| 元朗区| 鄱阳县| 保德县| 曲靖市| 班戈县| 神池县| 灵寿县| 隆安县| 华容县| 汤阴县| 婺源县| 衢州市| 怀远县| 无锡市| 青冈县| 大埔区| 德阳市| 会东县| 和平区| 丹巴县| 囊谦县| 德阳市| 文成县| 岳池县| 新晃| 县级市| 武山县| 宿松县| 佛山市| 清苑县| 海原县| 乌兰浩特市| 鱼台县| 车致| 鲜城| 海城市| 景德镇市| 舞钢市| 汪清县|