MySQL中有三種日誌文件,redo log、bin log、undo log。redo log 是 存儲引擎層(innodb)生成的日誌,主要爲了保證數據的可靠性;bin log 是 MySQL 數據庫層面上生成的日誌,主要用於 point in time 恢復和主從複製。undo log 主要用於事務的回滾(undo log 記錄的是每一個修改操做的逆操做) 和 一致性非鎖定讀(undo log 回滾行記錄到某種特定的版本---MVCC 多版本併發控制)。html
redo log 和 undo log 都是存儲引擎層面上生成的日誌,而且都記錄了數據的修改:只不過 redo log記錄的是"物理級別"上的頁修改操做,好比頁號xxx、偏移量yyy寫入了'zzz'數據;而undo log 記錄的是邏輯操做日誌,好比對某一行數據進行了INSERT語句操做,那麼 undo log就記錄一條與之相反的DELETE操做。mysql
MySQL做爲一個存儲系統,爲了保證數據的可靠性,最終得落盤。可是,又爲了數據寫入的速度,須要引入基於內存的"緩衝池"。其實不止MySQL,這種引入緩衝來解決速度問題的思想無處不在。既然數據是先緩存在緩衝池中,而後再以某種方式刷新到磁盤,那麼就存在因宕機致使的緩衝池中的數據丟失,爲了解決這種狀況下的數據丟失問題,引入了redo log。在其餘存儲系統,好比Elasticsearch中,也有相似的機制,叫translog。sql
可是通常討論數據寫入時,在MySQL中,通常叫事務操做,根據事務的ACID特性,如何保證一個事務提交後Durability的保證?而這就是 redo log 的做用。當向MySQL寫用戶數據時,先寫redo log,而後redo log根據"某種方式"持久化到磁盤,變成redo log file,用戶數據則在"buffer"中(好比數據頁、索引頁)。若是發生宕機,則讀取磁盤上的 redo log file 進行數據的恢復。從這個角度來講,MySQL 事務的持久性是經過 redo log 來實現的。數據庫
在事務運行過程當中,會不斷地產生 redo log,這些 redo log 會先定入 redo log buffer中,而後再將 redo log buffer 中的數據以某些方式順序地寫入到磁盤(各個操做的redo log 彙總到 redo log buffer,再由 redo log buffer 統一寫磁盤,就能作到順序寫了)。這些方式有:緩存
MySQL master 線程週期性任務 每秒一次,將 redo log buffer 刷新到磁盤(即便這個事務還沒有提交)併發
MySQL master 線程週期性任務 每10秒一次,將 redo log buffer 刷新到磁盤異步
當redo log buffer size 剩餘空間小於1/2時(innodb_log_buffer_size參數),將 redo log buffer 刷新到磁盤async
當 redo log file 大小已經達到某個域值快要"不可用"時(日誌文件組輪流寫文件),觸發 async/sync flush checkpoint,及時將一些髒頁刷新到磁盤,並同時將redo log buffer刷新到磁盤,而後更新redo log file 相應的 log sequence number值。線程
redo log buffer 的刷新到磁盤的時機由參數 innodb_flush_log_at_trx_commit 參數控制,可取的值有:0、一、2:3d
redo log 寫入磁盤時,是以扇區大小512B寫入的,保證每次寫都能寫入成功,不須要有 double write 機制。