0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MySQL事務(wù)日志

數(shù)據(jù)分析與開發(fā) ? 來源:數(shù)據(jù)分析與開發(fā) ? 作者:Java建設(shè)者 -神韻 ? 2020-11-14 09:58 ? 次閱讀

大家都清楚,日志是 MySQL 數(shù)據(jù)庫的重要組成部分,記錄著數(shù)據(jù)庫運(yùn)行期間各種狀態(tài)信息。MySQL 日志主要包括「錯誤日志」、「查詢?nèi)罩尽?、「慢查詢?nèi)罩尽?、「二進(jìn)制日志(binlog)」和 事務(wù)日志(redo log、undo log)幾大類。

其中,「二進(jìn)制日記」和「事務(wù)日記」尤為重要,一直被人重視、深入研究;可是事實(shí)很殘忍,重視或者說大多數(shù)人一般都是了解個表面,真正懂得人并不多。真想攻破這兩塊日記必須下血本,而且還不一定能攻破。但是不要緊,為了讓你們省下血本還能順利攻破這兩塊日記,我連續(xù)研究幾周 MySQL日記,最終肝出了這篇文章。

必要概念字典介紹

基礎(chǔ)不牢地動山搖,還是常規(guī)套路,先把必要知識普及/溫習(xí)一遍,當(dāng)后續(xù)文章出現(xiàn)疑慮反過來看下這些概念字典,說不定能柳暗花明又一村呢?

寫了又寫,想了又想,糾結(jié)了好久,這部分知識確實(shí)有點(diǎn)多,最后還是決定將這些必要概念字典單獨(dú)分出一個文章,后續(xù)打算用截圖方式引入各個章節(jié)中,建議遇到不懂名詞查閱一下字典。


圖1:進(jìn)階知識部分示意圖

認(rèn)識二進(jìn)制日記(Binlog)

Binlog 概念

Binlog 是邏輯日記,用于記錄數(shù)據(jù)庫執(zhí)行的寫入操作(查詢不記錄)信息,Server層記錄和引擎層無關(guān),并且是以追加方式進(jìn)行寫入,可以通過參數(shù)max_binlog_size設(shè)置每個 Binlog 文件的大小,文件大小達(dá)到設(shè)定值時會生成新的文件來保存日記。


Binlog 作用

在實(shí)際應(yīng)用中,主要用在兩個場景:主從復(fù)制和數(shù)據(jù)恢復(fù)

主從復(fù)制場景:在 Master 主端開啟 Binlog,將 Binlog 發(fā)生到各個 Slave 從端,Slave 從端重放 Binlog 從而達(dá)到主從數(shù)據(jù)一致

數(shù)據(jù)恢復(fù)場景:通過使用 mysqlbinlog 工具來恢復(fù)數(shù)據(jù)

Binlog 記錄過程及刷盤時機(jī)

Binlog 大致記錄過程是先寫 Binlog Buffer,然后通過刷盤時機(jī),控制刷入 OS Buffer,控制 fsync() 進(jìn)行寫入 Binlog File 日記磁盤的過程。


對于 Binlog,MySQL 是通過參數(shù) sync_binlog 參數(shù)來控制刷盤時機(jī),取值是 0、1 和 N 三種值。0 表示由系統(tǒng)自行判斷何時調(diào)用 sync() 寫入磁盤;1 表示每次事務(wù) commit 都要調(diào)用 fsync() 寫入磁盤;N 表示每 N 個事務(wù),才會調(diào)用 fsync() 寫入磁盤。


圖2:內(nèi)存和磁盤日記結(jié)構(gòu)圖

Binlog 記錄格式

MySQL 5.7.7 版本之前默認(rèn)格式是STATEMENT,版本之后默認(rèn)是ROW,可以通過參數(shù) binlog-format 指定。

認(rèn)識事務(wù)日記(Undo log)

Undo log 概念

Undo log是邏輯日記、回滾日記。比如一條修改 +3 的邏輯語句,Undo log 會記錄對應(yīng)一條 -3 的邏輯日記,一條插入語句則會記錄一條刪除語句,這樣發(fā)生錯誤時,根據(jù)執(zhí)行 Undo log 就可以回滾到事務(wù)之前的數(shù)據(jù)狀態(tài)。

Undo log 作用

回滾數(shù)據(jù):當(dāng)程序發(fā)生異常錯誤時等,根據(jù)執(zhí)行 Undo log 就可以回滾到事務(wù)之前的數(shù)據(jù)狀態(tài),保證原子性,要么成功要么失敗。

MVCC 一致性視圖:通過 Undo log 找到對應(yīng)的數(shù)據(jù)版本號,是保證 MVCC 視圖的一致性的必要條件。

Undo log 記錄過程及刷盤時機(jī)

刷盤過程及時機(jī)類似于 Binlog 和 Redo,可以參考 Redo log 刷盤時機(jī)章節(jié)給出的圖片,已經(jīng)體現(xiàn)出來了。

Undo log 總結(jié)

Undo log 日記內(nèi)容不是很多,重點(diǎn)是回滾和多版本控制 MVCC那塊。此外,我記得印象筆記深刻的是長事務(wù)會導(dǎo)致日記過多,這個日記就是 Undo log。因?yàn)殚L事務(wù)存在,導(dǎo)致需要保存很多視圖快照,其實(shí)這里就是涉及到Undo log 何時刪除和生成的問題,當(dāng)時糾結(jié)好久,其實(shí)很簡單。生成是事務(wù)開始后寫 Redo log 之前生成,當(dāng)沒有事務(wù)需要用到 Undo log 時就會被刪除。舉個例子,如果事務(wù) A 一直存活,那么事務(wù) A 之后產(chǎn)生的事務(wù) B、C...等等就算提交了,也不會被刪除,因?yàn)槭聞?wù) A 需要用到 B、C... 事務(wù)去找 A 的版本。所以避免長事務(wù)可以減少Undo log 日記量,當(dāng)然還可以提高性能。

認(rèn)識事務(wù)日記 (Redo log)

Redo log 概念

Redo log 是重做日記,屬于InnoDB引擎的日記。是物理日記,日記記錄的內(nèi)容的是數(shù)據(jù)頁的更改,這個頁 “做了什么改動”。如:add xx記錄 to Page1,向數(shù)據(jù)頁P(yáng)age1增加一個記錄。


Redo log 作用

前滾操作:具備crash-safe能力,提供斷電重啟時解決事務(wù)丟失數(shù)據(jù)問題。

提高性能:先寫Redo log記錄更新。當(dāng)?shù)鹊接锌臻e線程、內(nèi)存不足、Redo log滿了時刷臟。寫 Redo log 是順序?qū)懭?,刷臟是隨機(jī)寫,節(jié)省的是隨機(jī)寫磁盤的 IO 消耗(轉(zhuǎn)成順序?qū)懀?,所以性能得到提升。此技術(shù)稱為WAL技術(shù):Write-Ahead Logging,它的關(guān)鍵點(diǎn)就是先寫日記磁盤,再寫數(shù)據(jù)磁盤。

Redo log 兩階段提交

更新內(nèi)存后引擎層寫 Redo log 將狀態(tài)改成 prepare 為預(yù)提交第一階段,Server 層寫 Binlog,將狀態(tài)改成 commit為提交第二階段。兩階段提交可以確保 Binlog 和 Redo log 數(shù)據(jù)一致性。

Redo log 容災(zāi)恢復(fù)過程

MySQL的處理過程如下

判斷 redo log 是否完整,如果判斷是完整(commit)的,直接用 Redo log 恢復(fù)

如果 redo log 只是預(yù)提交 prepare 但不是 commit 狀態(tài),這個時候就會去判斷 binlog 是否完整,如果完整就提交 Redo log,用 Redo log 恢復(fù),不完整就回滾事務(wù),丟棄數(shù)據(jù)。

只有在 redo log 狀態(tài)為 prepare 時,才會去檢查 binlog 是否存在,否則只校驗(yàn) redo log 是否是 commit 就可以啦。怎么檢查 binlog:一個完整事務(wù) binlog 結(jié)尾有固定的格式。

Redo log 刷盤時機(jī)

Undo log 的刷盤時機(jī)和 Redo log 差不多,但是對于 Undo log 我沒找到對應(yīng)的刷盤參數(shù)設(shè)計(jì),所以不在提。Redo log 每次先寫入 Redo Log Buffer 中,然后通過刷盤時機(jī)控制刷入 OS Buffer 時間和刷入日記磁盤的時間。


圖3:內(nèi)存和磁盤日記結(jié)構(gòu)圖

在 Undo Log 中,MySQL 是通過參數(shù)innodb_flush_log_at_trx_commit來控制刷盤時機(jī),取值是 0、1 和 2三種值。0 表示事務(wù)提交后,每秒寫入 OS Buffer 并調(diào)用 fsync() 寫入日記磁盤中;1 表示每次事務(wù)提交會寫入OS Buffer 并調(diào)用 fsync() 將日記寫入日記磁盤中。2 表示事務(wù)每次提交寫入到 OS Buffer,每秒調(diào)用 fsync() 寫入日記磁盤。可見參數(shù)為 1 是最安全的,同時也是默認(rèn)值。


圖4:Redo log刷盤時機(jī)參數(shù)對應(yīng)操作圖

Redo log 存儲方式


圖5:Redo log File 環(huán)形存儲結(jié)構(gòu)圖

上圖是日記磁盤的 Redo log 環(huán)形設(shè)計(jì)圖(從頭寫,寫到結(jié)束又從頭開始寫~循環(huán))。write pos 和 check point 是兩個指針,write pos指針指向當(dāng)前日記文件寫入的位置,check point 指針指向當(dāng)前要擦除的開始位置。圖中綠色部分是可以寫入 Redo log 地方,每次寫入,write pos 指針會順時針推進(jìn),當(dāng)然基本不會與 check point 指針重合,因?yàn)?MySQL 有這種機(jī)制去實(shí)現(xiàn),每次觸發(fā)檢查點(diǎn)checkpoint,check point 會指針向前推進(jìn),這個過程就是需要進(jìn)行刷日記和數(shù)據(jù)磁盤,記錄相應(yīng)的 LSN,引出難點(diǎn) LSN。

Redo Log 檢查點(diǎn)

啥時候會觸發(fā)檢查點(diǎn) checkpoint


圖6:檢查點(diǎn)觸發(fā)時機(jī)

「Checkpoint 發(fā)生的時間、條件及臟頁的選擇等都非常復(fù)雜。而 Checkpoint 所做的事情無外乎是將緩沖池中的臟頁刷回到磁盤,不同之處在于每次刷新多少頁到磁盤,每次從哪里取臟頁,以及什么時間觸發(fā) Checkpoint。這些本文不會去研究」。

Redo Log LSN

LSN 這個概念,比較復(fù)雜。LSN 稱為日志的邏輯序列號(log sequence number),在 innodb 存儲引擎中,lsn占用 8 個字節(jié)。LSN 的值會隨著日志的寫入而逐漸增大?!缚梢院唵卫斫釹LN就是記錄從開始到現(xiàn)在已經(jīng)產(chǎn)生了多少字節(jié)的Redo log值」。

存儲方式兩個指針又是通過 LSN 計(jì)算得到指向位置,因?yàn)?LSN 記錄的是文件的大小字節(jié),當(dāng)超過文件大小時,需要用取模計(jì)算出這兩個指針位置,取模使得寫入就會從頭開始寫,這樣使得兩個指針在一個文件中,一直落在循環(huán)位置,你追我趕的過程。這就是 Redo log 環(huán)形邏輯思想設(shè)計(jì)實(shí)現(xiàn)。

上面提到LSN比較復(fù)雜,是因?yàn)樗泻芏鄠€值,輸入命令 show engine innodb status; ,可以看到四個的 lsn 記錄


圖7:LSN值列表

為了方便識別,我都為它們重新命名,如下所示。名詞記不住,后面無法繼續(xù)深入

內(nèi)存日記:redo log buffer lsn;磁盤日記:redo log file lsn;

一般關(guān)系為:redo log buffer lsn >= redo log file lsn,如果刷盤時機(jī)為1,則redo log buffer lsn = redo log file lsn。

內(nèi)存數(shù)據(jù)頁:data buffer lsn;數(shù)據(jù)磁盤數(shù)據(jù)頁:data disk lsn;

一般關(guān)系為data buffer lsn > data disk lsn,如果已經(jīng)刷入數(shù)據(jù)磁盤,則data buffer lsn = data disk lsn。

檢查點(diǎn):chckpoint lsn;

后面提到檢查點(diǎn)刷盤,數(shù)據(jù)刷盤和日記刷盤(如果有日記刷盤:則說明我假設(shè)的日記刷盤的時機(jī)設(shè)置值不為1,為1 是同步的,即始終 redo log buffer lsn = redo log file lsn,不會由檢查點(diǎn)觸發(fā)刷日記磁盤)。

都說 Redo log 是環(huán)形記錄,那么怎么記錄的?下面結(jié)合 LSN 給出記錄過程虛構(gòu)圖,可以對比 Redo log 存儲方式圖

?

相關(guān)知識:日記磁盤 + redo log file lsn + checkpoint lsn + 雙指針(write pos、check point)

?

1-8 按時間順序發(fā)生。1 點(diǎn)是假設(shè)最初的狀態(tài);2、3 點(diǎn)寫日記磁盤;4 點(diǎn)是觸發(fā)了檢查點(diǎn) checkpoint,進(jìn)行刷盤,「checkpoint lsn=1開始」,刷盤結(jié)束并更新「checkpoint lsn=512」。在 5 點(diǎn)、6 點(diǎn)已經(jīng)刷過了一循環(huán)內(nèi)存、二循環(huán)內(nèi)存,「從頭開始寫入 log,兩個指針指向回到了頭部」。第 7 點(diǎn)也是一個觸發(fā) checkpoint 的過程。9 點(diǎn)是假設(shè)沒有更新,最后達(dá)到平衡的結(jié)果,即內(nèi)存中數(shù)據(jù)頁和日記都完成了刷盤。


圖8:Redo Log File存儲過程

整個流程:

在某些情況下,觸發(fā) checkpoint,觸發(fā)數(shù)據(jù)頁和日志頁刷盤,此時將內(nèi)存中的臟數(shù)據(jù)---數(shù)據(jù)臟頁和日志臟數(shù)據(jù)"分別刷到數(shù)據(jù)磁盤和日記磁盤中,而且兩者刷盤速度不一樣。checkpoint 會保護(hù)機(jī)制,當(dāng)數(shù)據(jù)刷盤速度超過日志刷盤時,將會暫時停止數(shù)據(jù)刷盤,等待日志刷盤進(jìn)度超過數(shù)據(jù)刷盤。

刷盤時,對于數(shù)據(jù)磁盤,全部都是在內(nèi)存中,此時每次刷一個數(shù)據(jù)頁到內(nèi)存更新數(shù)據(jù)頁也更新了「data disk lsn」為「data buffer lsn」(在更新內(nèi)存數(shù)據(jù)頁時,會更新data buffer lsn)「?!?/p>

對于日記磁盤,除了要記錄 checkpoint lsn 的值為檢查點(diǎn) checkpoint的值(必須在結(jié)束時直接記錄一個值,速度很快),這里是針對日記刷盤時機(jī)不是1(1是同步緩存刷日記刷盤)時,并且日記還沒刷到日記磁盤需要觸發(fā)將緩存中日記提前刷到日記磁盤中,此時會將redo buffer log刷到redo log file中也更新了redo log file lsn為redo log buffer lsn。

模擬檢查點(diǎn)觸發(fā)前后,整個流程變化,一個數(shù)據(jù)頁和日記,「數(shù)據(jù)變化及l(fā)sn從179-180的變化圖(刷盤時機(jī)不為1)」


Redo log 容災(zāi)恢復(fù)過程與 LSN

Redo log 容災(zāi)恢復(fù)過程和 LSN 的知識,再次細(xì)化 Redo log 恢復(fù)過程

重啟 innodb 時,Redo log 完不完整,采用 Redo log 相關(guān)知識。用 Redo log 恢復(fù),啟動數(shù)據(jù)庫時,InnoDB 會掃描數(shù)據(jù)磁盤的數(shù)據(jù)頁 data disk lsn 和日志磁盤中的 checkpoint lsn。兩者相等則從 checkpoint lsn 點(diǎn)開始恢復(fù),恢復(fù)過程是利用 redo log 到 buffer pool,直到 checkpoint lsn 等于 redo log file lsn,則恢復(fù)完成。

如果 checkpoint lsn 小于 data disk lsn,說明在檢查點(diǎn)觸發(fā)后還沒結(jié)束刷盤時數(shù)據(jù)庫宕機(jī)了。因?yàn)?checkpoint lsn 最新值是在數(shù)據(jù)刷盤結(jié)束后才記錄的,檢查點(diǎn)之后有一部分?jǐn)?shù)據(jù)已經(jīng)刷入數(shù)據(jù)磁盤,這個時候數(shù)據(jù)磁盤已經(jīng)寫入部分的部分恢復(fù)將不會重做,直接跳到?jīng)]有恢復(fù)的 lsn 值開始恢復(fù)。

了解 ChangeBuffer

為啥提到 ChangeBuffer

為啥本文我會提到 ChangeBuffer 呢,其實(shí)很多時候會將 ChangeBuffer 和 Redo log 搞混,兩者都是巧用內(nèi)存,減少磁盤 IO,為了不弄混我覺得有必要專門對這個進(jìn)行一個講解。

ChangeBuffer 概念及作用

下面是我對 ChangeBuffer 的簡單介紹


也就是說對于更新的操作,如果用到了 ChangeBuffer,更新的數(shù)據(jù)所在的數(shù)據(jù)頁如果不在內(nèi)存中,將不用去數(shù)據(jù)磁盤將數(shù)據(jù)頁讀到內(nèi)存,而是將這一次操作記錄在 ChangeBuffer 中,「ChangeBuffer 主要節(jié)省的則是隨機(jī)讀磁盤的 IO 消耗」,下次讀取查詢等讀取數(shù)據(jù)頁時用上 ChangeBuffer 中的記錄即可。其實(shí)也是一種巧用內(nèi)存的思想。

ChangeBuffer 與 Redo log 區(qū)別

Redo log 主要節(jié)省的是隨機(jī)寫磁盤的 IO 消耗(轉(zhuǎn)成順序?qū)懀?ChangeBuffer 主要節(jié)省的則是隨機(jī)讀磁盤的 IO 消耗

這句話怎么理解,看下面:

Redo log 與 ChangeBuffer (含磁盤持久化) 這 2 個機(jī)制,不同之處在于優(yōu)化了整個變更流程的不同階段。

先不考慮 Redo log、ChangeBuffer 機(jī)制,簡化抽象一個更新 (insert、update、delete) 流程:

從磁盤讀取待變更的行所在的數(shù)據(jù)頁,讀入內(nèi)存頁中

對內(nèi)存頁中的行,執(zhí)行變更操作

將變更后的數(shù)據(jù)頁,寫入至數(shù)據(jù)磁盤中

其中,流程中的步驟 1 涉及隨機(jī)讀磁盤 IO;步驟 3 涉及隨機(jī)寫磁盤 IO;剛好對應(yīng) ChangeBuffer 和 Redo log。

對那句話的理解答案:

ChangeBuffer 機(jī)制,優(yōu)化了步驟 1——避免了隨機(jī)讀磁盤 IO ,將不在內(nèi)存中的數(shù)據(jù)頁的操作寫入ChangeBuffer 中,而不是將數(shù)據(jù)頁從磁盤讀入內(nèi)存頁中

Redo log 機(jī)制, 優(yōu)化了步驟 3——避免了隨機(jī)寫磁盤 IO,將隨機(jī)寫磁盤,優(yōu)化為了順序?qū)懘疟P(寫 Redo log,確保 crash-safe)

有沒有用到 ChangeBuffer 對于 Redo log 的區(qū)別

Redo log 機(jī)制,為了保證 crash-safe,一直都會用到。有無用到 ChangeBuffer 機(jī)制,對于 redo log 這步的區(qū)別在于—— 用到了 ChangeBuffer 機(jī)制時,在 Redo log 中記錄的本次變更,是記錄 new change buffer item 相關(guān)的信息,而不是直接的記錄物理頁的變更。在我們 mysql innodb 中, ChangeBuffer 機(jī)制不是一直會被應(yīng)用到,僅當(dāng)待操作的數(shù)據(jù)頁當(dāng)前不在內(nèi)存中,需要先讀磁盤加載數(shù)據(jù)頁時,ChangeBuffer 才有用武之地。

ChangeBuffer的 merge 過程


除了訪問這個數(shù)據(jù)頁會觸發(fā) merge 外,系統(tǒng)有后臺線程會定期 merge。在數(shù)據(jù)庫正常關(guān)閉(shutdown)的過程中,也會執(zhí)行 merge 操作。

merge 過程做三步

從磁盤讀入數(shù)據(jù)頁到內(nèi)存(老版本的數(shù)據(jù)頁);

從 change buffer 里找出這個數(shù)據(jù)頁的 change buffer 記錄 (可能有多個),依次應(yīng)用,得到新版數(shù)據(jù)頁;

寫 redo log。這個 redo log 包含了數(shù)據(jù)的變更和 change buffer 的變更。

日記大連貫U-R-B,一舉攻破拿下

前面分別講的是 Binlog、Undo log 和 Redo log,下面將他們都串聯(lián)起來,在一些流程體現(xiàn)全部日記。

同樣,以一些最經(jīng)典的更新語句例子展開說明。

制造演示數(shù)據(jù)

測試語句:插入語句+查詢語句,a字段是普通索引

1、insert into ta(a,b) values(2,5),(7, 5) 2、select * from t where a in (2, 7)

假設(shè)原來的數(shù)據(jù)如下圖,數(shù)據(jù)頁 page1 在內(nèi)存中,page2 不在。插入的數(shù)據(jù) (2,5) 落在 page1,數(shù)據(jù) (7,5) 落在page2 中。


假設(shè)沒有日記和 ChangeBuffer 示范

先不考慮所有日記及 ChangeBuffer 機(jī)制,簡化抽象一個更新 insert 流程

從磁盤讀取待變更的行所在的數(shù)據(jù)頁,讀入內(nèi)存頁中

對內(nèi)存頁中的行,執(zhí)行變更操作

將變更后的數(shù)據(jù)頁,寫入至數(shù)據(jù)磁盤中


考慮所有日記和 ChangeBuffer 示范--現(xiàn)有 Innodb 流程

過程是 兩階段提交-----日記刷盤------數(shù)據(jù)刷盤(涉及 Redo log lsn 和 ChangeBuffer 的內(nèi)容)

兩階段提交過程

數(shù)據(jù) (2,5) 所在頁 page 1 在內(nèi)存中直接更新內(nèi)存;數(shù)據(jù) (7,5) 所在頁 page 2 不在內(nèi)存中,記錄 change buffer(具有唯一性的索引或者沒有使用 change buffer 的操作是將磁盤中的數(shù)據(jù)頁讀入內(nèi)存中并做更新)。

寫 undo 日記?!赶葘懢彺?,后面根據(jù)刷盤參數(shù)決定何時刷入磁盤,后面的 redo/Binlog 都一樣」。日記刷盤 在每一個日記中基本已經(jīng)提到,它和設(shè)置的參數(shù)有關(guān),下文不會再展開介紹。

寫 redo 日記(先記在內(nèi)存中的更新,然后記不在內(nèi)存中的 change buffer 的改變)

日記狀態(tài)改成 prepare 階段。

寫 Binlog日記。

提交事務(wù),日記狀態(tài)改成 commit 階段。


merge 過程

緊接著上文,圖片可上下參考,假設(shè)現(xiàn)在執(zhí)行查詢語句 select * from t where a in (2, 7) ,此次查詢索引 a=7 所在的數(shù)據(jù)頁不在內(nèi)存中,并且上一步更新已經(jīng)在 change buffer 中有記錄,將會觸發(fā) merge 過程

將 page 2 讀入內(nèi)存

依次應(yīng)用 change buffer 中的記錄,得到最新版數(shù)據(jù)頁

寫入 redo,之前記錄的 changebuffer 改動,現(xiàn)在改成數(shù)據(jù)頁的改動

至于 changebuffer 被應(yīng)用后是刪除還是標(biāo)記,還有 redo 中原有的記錄 changebuffer 的改動怎么調(diào)整是刪除還是修改成數(shù)據(jù)頁的改動這里下面的圖是按照自己的想法描述出來,如有誤望留言指正。


數(shù)據(jù)刷盤過程

數(shù)據(jù)刷盤 flush 的有四種情況

InnoDB 的 redo log 寫滿了。這時候系統(tǒng)會停止所有更新操作,把 checkpoint 往前推進(jìn),redo log 留出空間可以繼續(xù)寫

系統(tǒng)內(nèi)存不足。當(dāng)需要新的內(nèi)存頁,而內(nèi)存不夠用的時候,就要淘汰一些數(shù)據(jù)頁,空出內(nèi)存給別的數(shù)據(jù)頁使用。如果淘汰的是臟頁,就要先將臟頁寫到磁盤

MySQL 認(rèn)為系統(tǒng)空閑的時候

MySQL 正常關(guān)閉的情況

數(shù)據(jù)刷盤也代表著 Redo log 檢查點(diǎn) checkpoint 觸發(fā),較為復(fù)雜。

假設(shè)數(shù)據(jù)刷盤 flush 的四種情況發(fā)生了一種,那么聯(lián)系上文的過程將如下

將臟頁從內(nèi)存中刷回到數(shù)據(jù)磁盤

刷完后更新檢查點(diǎn) checkpoint 的值


流程中間某個環(huán)節(jié)數(shù)據(jù)庫宕機(jī)后,恢復(fù)具體過程,這些留在心里了,沒往上去寫,讀者可以自行思考,不難。

結(jié)尾

整個文章講了 Binlog、Undo log 和 Redo log,隨帶一提 ChangeBuffer,對此,講到這里,基本上要把我要將的已經(jīng)講完,內(nèi)容挺多,有耐心可以慢慢啃,不懂歡迎留言!

思考環(huán)節(jié),下面留下兩個問題,歡迎大家留言解答

1、為啥 Binlog 沒有 crash-safe 功能?

2、保證 crash-safe 為啥要用兩個日記,不能用一個日記嗎(Redo log 或 Binglog)?

責(zé)任編輯:xj

原文標(biāo)題:面試官的靈魂一擊:你懂 MySQL 事務(wù)日志嗎?

文章出處:【微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3799

    瀏覽量

    64389
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    809

    瀏覽量

    26569

原文標(biāo)題:面試官的靈魂一擊:你懂 MySQL 事務(wù)日志嗎?

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    1個工具4類日志,幫你解決99%的問題

    眾所周知,通過日志可以對研發(fā)過程中,以及模組運(yùn)行過程中的各種故障進(jìn)行分析,快速定位和解決問題。 但新手朋友往往念叨著“抓日志”,卻又無從下手……此時就不得不提到工程師朋友的寶藏工具
    的頭像 發(fā)表于 12-17 16:26 ?71次閱讀
    1個工具4類<b class='flag-5'>日志</b>,幫你解決99%的問題

    MySQL還能跟上PostgreSQL的步伐嗎

    Percona 的老板 Peter Zaitsev最近發(fā)表一篇博客,討論了MySQL是否還能跟上PostgreSQL的腳步。Percona 作為MySQL 生態(tài)扛旗者,Percona 開發(fā)了知名
    的頭像 發(fā)表于 11-18 10:16 ?216次閱讀
    <b class='flag-5'>MySQL</b>還能跟上PostgreSQL的步伐嗎

    Spring事務(wù)實(shí)現(xiàn)原理

    作者:京東零售 范錫軍 1、引言 spring的spring-tx模塊提供了對事務(wù)管理支持,使用spring事務(wù)可以讓我們從復(fù)雜的事務(wù)處理中得到解脫,無需要去處理獲得連接、關(guān)閉連接、事務(wù)
    的頭像 發(fā)表于 11-08 10:10 ?825次閱讀
    Spring<b class='flag-5'>事務(wù)</b>實(shí)現(xiàn)原理

    適用于MySQL的dbForge架構(gòu)比較

    dbForge Schema Compare for MySQL 是一種工具,用于輕松有效地比較和部署 MySQL 數(shù)據(jù)庫結(jié)構(gòu)和腳本文件夾差異。該工具提供了 MySQL 數(shù)據(jù)庫架構(gòu)中所有差異的全面視圖。
    的頭像 發(fā)表于 10-28 09:41 ?210次閱讀
    適用于<b class='flag-5'>MySQL</b>的dbForge架構(gòu)比較

    nginx日志配置方法

    access_log用來定義日志級別,日志位置。
    的頭像 發(fā)表于 10-24 17:43 ?230次閱讀

    Linux日志管理經(jīng)驗(yàn)總結(jié)

    日志內(nèi)容,合理的日志內(nèi)容(日志錨點(diǎn),內(nèi)容格式,等)可以為應(yīng)用服務(wù)的執(zhí)行記錄、問題排查提供最有力的幫助。
    的頭像 發(fā)表于 10-24 17:36 ?214次閱讀

    日志篇:模組日志總體介紹

    ?今天我們學(xué)習(xí)合宙模組日志總體介紹,以下進(jìn)入正文。 一、本文討論的邊界 本文是對合宙 4G 模組, 以及 4G+GNSS 模組的日志功能的總體介紹。通過日志,可以對研發(fā)過程中,以及模組運(yùn)行過程中
    的頭像 發(fā)表于 10-24 07:16 ?196次閱讀
    <b class='flag-5'>日志</b>篇:模組<b class='flag-5'>日志</b>總體介紹

    Jtti:如何查看yum命令的錯誤日志來診斷問題?

    在Linux系統(tǒng)中,當(dāng)yum命令無法正常工作時,查看錯誤日志是診斷問題的重要步驟。以下是一些方法,可以幫助你查看和分析yum命令的錯誤日志: 查看Yum歷史記錄 : 你可以通過 yum
    的頭像 發(fā)表于 10-14 15:51 ?231次閱讀

    MySQL知識點(diǎn)匯總

    大家好,這部分被稱為DQL部分,是每個學(xué)習(xí)MySQL必須要學(xué)會的部分,下面就讓我來介紹MySQL中的其他部分。
    的頭像 發(fā)表于 08-05 15:27 ?403次閱讀
    <b class='flag-5'>MySQL</b>知識點(diǎn)匯總

    奇怪!應(yīng)用的日志呢??

    1. 問題回顧 問題背景 是在進(jìn)行中臺應(yīng)用中間件遷移過程中,發(fā)現(xiàn)存在 項(xiàng)目啟動失敗 或者 項(xiàng)目正常啟動 (jsf正常掛載并正常運(yùn)行,mq正常發(fā)送和消費(fèi))但是 無任何日志打印 現(xiàn)象。 更奇怪 的是不打
    的頭像 發(fā)表于 06-11 10:48 ?318次閱讀
    奇怪!應(yīng)用的<b class='flag-5'>日志</b>呢??

    MySQL的整體邏輯架構(gòu)

    支持多種存儲引擎是眾所周知的MySQL特性,也是MySQL架構(gòu)的關(guān)鍵優(yōu)勢之一。如果能夠理解MySQL Server與存儲引擎之間是怎樣通過API交互的,將大大有利于理解MySQL的核心
    的頭像 發(fā)表于 04-30 11:14 ?453次閱讀
    <b class='flag-5'>MySQL</b>的整體邏輯架構(gòu)

    阿里二面:了解MySQL事務(wù)底層原理嗎

    MySQL 是如何來解決臟寫這種問題的?沒錯,就是鎖。MySQL 在開啟一個事務(wù)的時候,他會將某條記錄和事務(wù)做一個綁定。這個其實(shí)和 JVM 鎖是類似的。
    的頭像 發(fā)表于 01-18 16:34 ?337次閱讀
    阿里二面:了解<b class='flag-5'>MySQL</b><b class='flag-5'>事務(wù)</b>底層原理嗎

    MySQL密碼忘記了怎么辦?MySQL密碼快速重置方法步驟命令示例!

    MySQL密碼忘記了怎么辦?MySQL密碼快速重置方法步驟命令示例! MySQL是一種常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),如果你忘記了MySQL的密碼,不必?fù)?dān)心,可以通過一些簡單的步驟來快速重
    的頭像 發(fā)表于 01-12 16:06 ?751次閱讀

    騰訊科技獲區(qū)塊鏈網(wǎng)絡(luò)事務(wù)處理專利

    據(jù)專利摘要介紹,此方法涉及的步驟可概括如下:收集待處理事務(wù)數(shù)據(jù)集的統(tǒng)計(jì)信息,此數(shù)據(jù)集含有多個接收并待處理的事務(wù)數(shù)據(jù);制定獲取區(qū)塊鏈網(wǎng)絡(luò)對事務(wù)數(shù)據(jù)的打包標(biāo)準(zhǔn);如果統(tǒng)計(jì)信息符合打包要求,將事務(wù)
    的頭像 發(fā)表于 01-08 11:36 ?566次閱讀

    如何使用Golang連接MySQL

    首先我們來看如何使用Golang連接MySQL。
    的頭像 發(fā)表于 01-08 09:42 ?3379次閱讀
    如何使用Golang連接<b class='flag-5'>MySQL</b>