日誌系統主要有redo log(重作日誌)和binlog(歸檔日誌)。redo log是InnoDB存儲引擎層的日誌,binlog是MySQL Server層記錄的日誌, 二者都是記錄了某些操做的日誌(不是全部)天然有些重複(但二者記錄的格式不一樣)。mysql
圖來自極客時間的mysql實踐,該圖是描述的是MySQL的邏輯架構。sql
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
。3d
redo log日誌的大小是固定的,即記錄滿了之後就從頭循環寫。日誌
圖片來自極客時間,該圖展現了一組4個文件的redo log日誌,checkpoint以前表示擦除完了的,便可以進行寫的,擦除以前會更新到磁盤中,write pos是指寫的位置,當write pos和checkpoint相遇的時候代表redo log已經滿了,這個時候數據庫中止進行數據庫更新語句的執行,轉而進行redo log日誌同步到磁盤中。code
binlog是屬於MySQL Server層面的,又稱爲歸檔日誌,屬於邏輯日誌,是以二進制的形式記錄的是這個語句的原始邏輯,依靠binlog是沒有crash-safe
能力的blog
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 內部執行的,深色框表示是在執行器中執行的。
圖片來自極客時間.