Mysql 中寫操作時保駕護航的三兄弟!

2022-03-17 12:02:40 字數 3456 閱讀 6291

這期的文章主要是講述寫操作過程中涉及到的三個日誌檔案,看過前幾期的話可能你或多或少已經有些了解了(或者從別的地方也了解過)。比如整個寫操作過程中用到的兩階段提交,又或者是操作過程中涉及到的日誌檔案,但是總體來說不是很系統更談不上全面。

今天我們就來會會這三兄弟。

圖注:思維導圖

這個名詞你應該聽到過很多次了,在這裡再介紹下這位老朋友。

所謂的兩階段提交,從字面意思來看應該是有兩個步驟來進行約束的。事實上也是如此。這兩個步驟中的主角就是我們今天要講的重要角色中的兩位:binlog 和 redo log

提到兩階段提交,sql 語句的執行流程就繞不過去了。沒轍,雖然提了很多遍,但還得再拉出來溜溜。只不過這次的側重點和前面的會有些不同。

具體到操作流程上是這樣的:

當執行某個寫操作的 sql 時,引擎將這行資料更新到記憶體的同時把對應的操作記錄到 redo log 裡面,然後處於 prepare 狀態。並把完成資訊告知給執行器。

執行器生成對應操作的 binlog,並把 binlog 寫入磁碟裡。然後呼叫引擎的提交事務介面,變更 redo log 狀態為 commit,這樣操作就算完成了。

好了,知道了兩階段提交後,我們接下來看看這些日誌檔案的真面目。 

首先出場的是位於儲存引擎層的redo log,它是用來記錄在"資料頁做了什麼修改"的物理日誌檔案。

提到 redo log,wal 技術必然是繞不過去的,全稱是 write-ahead logging。也就是在同步磁碟前先寫日誌,然後系統再根據一定的策略將日誌裡的記錄同步到磁碟裡。

從上邊的兩階段提交的過程裡,我們可以看到 wal 技術的使用場景。不知道你有沒有疑惑,為什麼中間非要寫 redo log,直接將更新結果同步到磁碟裡不行嗎?傻孩子,同步到磁碟裡就意味著每次寫操作就得產生隨機寫盤操作,速度得多慢啊。

機智的你可能會說了,那我能不能一定的時間後從記憶體再同步到磁碟裡,這種方式不行嗎?來,先給你個腦瓜崩,你想想,我服務重啟了,這些資料還在不?記憶體是易失的,不知道什麼異常情況就會導致資料丟失。所以這時候就需要乙個能持久化的中間檔案,起到"緩衝"的作用,並且寫入速度還不慢。

那麼 redo log 就應運而生了。雖然同樣儲存在磁碟上,但是順序寫入在速度上並不受影響(疑惑的同學可以了解下磁碟的隨機與順序讀寫的區別)。

當然 redo log 除了能起到"延遲"同步磁碟檔案的作用外,在資料庫伺服器宕機時,還可以用來恢復資料。

談到寫入時機,是不是更疑惑了,難倒不是更新完記憶體就寫入 redo log 檔案嗎?答案確實不是,因為中間還有乙個 redo log buffer(記憶體中) 。mysql 每執行一條語句,會先將記錄寫入 redo log buffer,後續執行 commit 操作時會以一定的時機寫入到 redo log 檔案(磁碟上)中。

值得注意的是,redo log buffer 裡的資料是在執行 commit 操作時寫入到 redo log 檔案中的。

至於寫入的時機,則由下面的引數來控制的: 

(源自網路)

知道了寫入時機,這裡簡單介紹下寫入的方式吧。在 innodb 中,redo log 的大小是固定的,那麼就只能是以迴圈的方式進行寫入了。假如當前我有 4 個檔案,從第乙個檔案開始寫入,直到最後乙個檔案寫滿為止,再回到開頭將資料同步至檔案後擦除掉繼續寫。

圖中的 write pos 表示當前記錄的位置,隨著不斷寫入逐漸後移。當寫到 ib_logfile_3號檔案時,整個 redo log 就被寫滿了。此時更新操作就會被阻塞。系統根據 check point 標記位來擦除掉一些記錄(當然前提是把這些記錄同步至磁碟)。

總得來看 redo log 的寫入方式就是乙個不斷寫入,寫滿後擦除,又寫入的過程。

說完了 redo log,我們再來看看另乙個位於服務層的二進位制日誌檔案 binlog,這位大兄弟扮演的角色是儲存邏輯日誌的,所謂的邏輯日誌就是指修改了什麼,都會記錄其中。

例如:對 id = 1 的字段進行更新操作。

當然除了記錄操作過程外,它還有支援主從同步資料異常恢復的能力。

binlog 中有三種寫入模式,我們分別來看下有什麼不同及對應的優缺點:

(源自網路)

與 redo log 迴圈寫不同的是, binlog 採用追加的方式寫入,當乙個檔案寫到一定大小後就會切換到另乙個。

在上面的兩階段提交裡我們有提到過在寫入binlog 後會呼叫引擎的提交事務介面,變更 redo log 狀態為 commit。那麼它是如何找到對應的記錄,或者換句話說,它們兩者是怎麼關聯起來的呢?

答案是通過乙個共同的字段 xid,不僅在事務提交時,在崩潰恢復的時候如果遇到僅寫入 prepare 而沒有 commit 的 redo log,也可以通過 xid 去尋找對應的事務。

到這裡我們有必要回顧下寫流程的操作,以更新某個欄位為例:

到這裡,你可能會疑惑了,通篇裡哪有 undo log 的影子,你個渣男!

別急,來了!

根據字面意思,你應該能猜出來它是幹啥的。回滾嘛,也就是給你一次後悔的機會。在進行資料修改時,同時記錄 undo log,即同時記錄相反操作的邏輯日誌。你可以理解為操作 update 的時候,寫一條對應相反的 update 記錄,操作 delete 的時候,寫一條對應的 insert 記錄。 

當事務回滾時。從 undo log 中讀取到對應的邏輯記錄就可以進行回滾操作了。

兩階段提交

重做日誌

二進位制日誌

回滾日誌

虛偽的政策意在為高房價保駕護航

這兩天,伴隨著 和各部委幾記 重 拳,房地產市場開始出現了少有的恐慌情緒,以地產股為龍頭的滬深 出現了一定程度調整。然而,當政策謎底揭開時,近來遭受心理壓力的地方 開發商和炒房客們,發現打在身上的那些所謂的 重 拳,既像 棉花拳 更像按摩師常用的 鎚擊 手法。於是,他們終於從大家長 大義凜然 的外表...

在隱私的博弈時代,BCH為你保駕護航

在大資料時代,個人的交易資料隱私存在灰色地帶,多數隱私被人堂而皇之的買賣交易,甚至有人還表達出了這種觀點,交易隱私的洩露雖然與使用者的安全利益存在衝突,但是在大資料時代,沒有隱私的洩露,也就無法享受規模化資料所帶來的便利。那麼同理,在加密數字貨幣時代,即便數字貨幣本身就意味著強大的隱私屬性,但是剖析...

在隱私的博弈時代,BCH為你保駕護航

在大資料時代,個人的交易資料隱私存在灰色地帶,多數隱私被人堂而皇之的買賣交易,甚至有人還表達出了這種觀點,交易隱私的洩露雖然與使用者的安全利益存在衝突,但是在大資料時代,沒有隱私的洩露,也就無法享受規模化資料所帶來的便利。那麼同理,在加密數字貨幣時代,即便數字貨幣本身就意味著強大的隱私屬性,但是剖析...