日誌系統主要有redo log(重做日誌)和binlog(歸檔日誌)。redo log是InnoDB存儲引擎層的日誌,binlog是MySQL Server層記錄的日誌, 兩者都是記錄了某些操作的日誌(不是所有)自然有些重覆(但兩者記錄的格式不同)。 圖來自極客時間的mysql實踐,該圖是描述的是M ...
日誌系統主要有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中的內容更新到磁碟中,這裡涉及到WAL
即Write 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 內部執行的,深色框表示是在執行器中執行的。
圖片來自極客時間.