1. 程式人生 > >MySQL日誌系統:redo log與binlog

MySQL日誌系統:redo log與binlog

日誌系統主要有redo log(重做日誌)和binlog(歸檔日誌)。redo log是InnoDB儲存引擎層的日誌,binlog是MySQL Server層記錄的日誌, 兩者都是記錄了某些操作的日誌(不是所有)自然有些重複(但兩者記錄的格式不同)。

圖來自極客時間的mysql實踐,該圖是描述的是MySQL的邏輯架構。

redo log日誌模組

redo log是InnoDB儲存引擎層的日誌,又稱重做日誌檔案,用於記錄事務操作的變化,記錄的是資料修改之後的值,不管事務是否提交都會記錄下來。在例項和介質失敗(media failure)時,redo log檔案就能派上用場,如資料庫掉電,InnoDB儲存引擎會使用redo log恢復到掉電前的時刻,以此來保證資料的完整性。

在一條更新語句進行執行的時候,InnoDB引擎會把更新記錄寫到redo log日誌中,然後更新記憶體,此時算是語句執行完了,然後在空閒的時候或者是按照設定的更新策略將redo log中的內容更新到磁碟中,這裡涉及到WALWrite Ahead logging技術,他的關鍵點是先寫日誌,再寫磁碟。

有了redo log日誌,那麼在資料庫進行異常重啟的時候,可以根據redo log日誌進行恢復,也就達到了crash-safe

redo log日誌的大小是固定的,即記錄滿了以後就從頭迴圈寫。

圖片來自極客時間,該圖展示了一組4個檔案的redo log日誌,checkpoint之前表示擦除完了的,即可以進行寫的,擦除之前會更新到磁碟中,write pos是指寫的位置,當write pos和checkpoint相遇的時候表明redo log已經滿了,這個時候資料庫停止進行資料庫更新語句的執行,轉而進行redo log日誌同步到磁碟中。

binlog日誌模組

binlog是屬於MySQL Server層面的,又稱為歸檔日誌,屬於邏輯日誌,是以二進位制的形式記錄的是這個語句的原始邏輯,依靠binlog是沒有crash-safe能力的

redo log和binlog區別

  • redo log是屬於innoDB層面,binlog屬於MySQL Server層面的,這樣在資料庫用別的儲存引擎時可以達到一致性的要求。

  • redo log是物理日誌,記錄該資料頁更新的內容;binlog是邏輯日誌,記錄的是這個更新語句的原始邏輯

  • redo log是迴圈寫,日誌空間大小固定;binlog是追加寫,是指一份寫到一定大小的時候會更換下一個檔案,不會覆蓋。

  • binlog可以作為恢復資料使用,主從複製搭建,redo log作為異常宕機或者介質故障後的資料恢復使用。

一條更新語句執行的順序


update T set c=c+1 where ID=2;
  • 執行器先找引擎取 ID=2 這一行。ID 是主鍵,引擎直接用樹搜尋找到這一行。如果 ID=2 這一行所在的資料頁本來就在記憶體中,就直接返回給執行器;否則,需要先從磁碟讀入記憶體,然後再返回。

  • 執行器拿到引擎給的行資料,把這個值加上 1,比如原來是 N,現在就是 N+1,得到新的一行資料,再呼叫引擎介面寫入這行新資料。

  • 引擎將這行新資料更新到記憶體中,同時將這個更新操作記錄到 redo log 裡面,此時 redo log 處於 prepare 狀態。然後告知執行器執行完成了,隨時可以提交事務。

  • 執行器生成這個操作的 binlog,並把 binlog 寫入磁碟。

  • 執行器呼叫引擎的提交事務介面,引擎把剛剛寫入的 redo log 改成提交(commit)狀態,更新完成。

這個update語句的執行流程圖,圖中淺色框表示是在 InnoDB 內部執行的,深色框表示是在執行器中執行的。

圖片來自極客時間.