MySQL 事務未提交 redolog 能持久化到磁盤嗎?

👉 那意外情況導致事務還沒提交的時候,redolog 能不能被持久化到磁盤呢?

先公佈答案,確實有可能會!

爲什麼會有這種可能呢,難道是被動刷盤了?先不着急想象,我們接着往下看,這個問題今天必須拿下!

redo log 可能存在的位置

沒看過開頭提到的文章建議返回去看下,這裏再進行下核心知識點的回憶。

redo log 其實記錄的是此次事務「完成後」的數據狀態,記錄的是更新之後的值。

我們來回顧看下 redolog 的寫入流程:

  1. 1. 修改操作時先將原始數據從磁盤中讀入內存中來,修改數據,如圖中的髒頁

    1. 此時產生日誌寫入 redo logbuffer,記錄的是數據被修改後的值
  2. 3. 當事務 commit 時,將 redo logbuffer 中的內容採用追加方式刷新到 redo logfile

  3. 4. 調用 fsync 將修改的數據刷新到磁盤中

也就是說 redolog 可能存在於三種位置狀態:

redolog buffer:

寫入 redo log buffer 就用到了的 WAL(Write-Ahead Logging)技術,日誌先寫入 redo log buffer 緩衝區

page cache:

page cache 是文件系統緩衝,如果是寫到磁盤,但是沒有持久化(fsync),物理上是在文件系統的 page cache 裏面

硬盤 disk:

從 page cache 持久化到磁盤,也就是磁盤中的 redo log file 中,你在 data 目錄中看到的 ib_logfile 文件就是實際的 redo log 日誌文件,它以文件組的形式出現的。這些文件以ib_logfile[數字](數字可以是 0、1、2..)的形式進行命名。

事務提交的過程

一般來說事務的提交也應該有以下三個過程:

寫磁盤策略

緩存在 redo log buffer 裏的 redo log 是在內存中的,最終是要刷到磁盤中。

👉 那麼 redo log 是如何被控制寫入刷入磁盤的呢?

這就涉及到 redo log 的刷盤策略了

InnoDB 通過 innodb_flush_log_at_trx_commit 參數可以控制策略,該參數控制 commit 提交事務時,如何將 redo log buffer 中的日誌刷新到 redo log file 中,它支持設定 0,1, 2 也就是說支持三種策略設置。

這個策略我們可以用參數設置:

show variables like 'innodb_flush_log_at_trx_commit'
//默認情況下 innodb_flush_log_at_trx_commit值是1

Innodb 存儲引擎有一個後臺線程,每隔 1 秒,就會把 redo log buffer 中的內容寫到文件系統緩存(Page Cache),然後調用 fsync 進行刷入到磁盤的操作。

延遲寫

設置爲 0(延遲寫) :每次事務提交時不主動進行刷盤操作,redo log 依然留在 redo log buffer 中,然後後臺進程每秒寫入 page cache 中,然後持久化到磁盤中。

實時寫,實時刷

設置爲 1 (實時寫,實時刷):每次事務提交時都會直接將緩存在 redo log buffer 中的 redo log 直接持久化到磁盤中( 默認值 )。

實時寫,延時刷

設置爲 2(實時寫,延時刷) :表示每次事務提交時都只把 redo log buffer 內容寫入 page cache,不進行同步,由 os 自己決定什麼時候同步到磁盤文件。

事務未提交寫磁盤的情況

看了 redo log 可能存在的狀態和位置,以及寫盤策略,那跟事務是否提交 redo log 能否寫入磁盤有啥關係呢。

那我們看下面幾種情況是不是在事務沒提交的時候也可能會寫入到磁盤呢!

後臺線程每隔 1s 刷新

上面我們說到 InnoDB 有一個後臺線程,每隔 1 秒輪詢一次,具體的操作是這樣的:調用 write 將 redolog buffer 中的日誌寫到文件系統的 page cache,然後調用 fsync 持久化到磁盤。

那麼寫入到 redolog buffer 中的 redo log 在事務沒提交的時候,可能就會後臺線程在持久化的時候被一起持久化到磁盤中。

其他事務提交成功

我們在設置寫盤策略的時候 innodb_flush_log_at_trx_commit 設置爲 1,在每次事務提交的時候都會直接將緩存在 redo log buffer 中的 redo log 直接持久化到磁盤中。

舉個栗子,事務 A 執行到一半,此時 redolog 到 redolog buffer 中,這時候有另外一個事務 B 提交,事務 B 要把 redolog buffer 裏的日誌全部持久化到磁盤,這時候就會帶上是不是事務 A 在 redolog buffer 裏的日誌一起持久化到磁盤。

(⊙o⊙)…

redo log buffer 空間快滿了

另一種說法是當 redo log buffer 佔用的空間達到 redolog buffer 大小一半的時候,後臺線程會主動寫盤。

redo log buffer 佔用空間由參數 innodb_log_buffer_size 控制,默認是 8MB

但是這個寫盤動作只是 write 到了文件系統的 page cache,仍然是在內存中,並沒有調用 fsync 真正落盤。

🔔朋友們下次當面試官問你:事務還沒提交的時候,redo log 能不能被持久化到磁盤呢?

你應該知道如何回答了吧,哈哈,拿下!

歡迎朋友們關注我的公衆號📢📢:【小許 code】!🤣🤣

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Bmy7eofHKepcdo0d6rILMQ