上節咱們講到,建議將 redo log
的刷盤策略設置爲1:即提交事務時,強制將 redo log buffer
裏的 redo log
刷入到磁盤後纔算事務提交成功。緩存
可是咱們都知道,redo log buffer
是 InnoDB 存儲引擎的組件,而 MySQL 支持不少種存儲引擎,那麼 MySQL 在撇除存儲引擎後,本身就沒有記錄一下關於數據更新的日誌嗎?spa
redo log
自己是 InnoDB 存儲引擎特有的一個東西,因此 MySQL 也提供了一種全部存儲引擎共享的日誌文件,叫 binlog
。日誌
因此在提交事務時,不但會有 rodo log
,還有會 binlog
產生。code
binlog 寫入到哪裏?事務
因爲 binlog
不是 innoDB 存儲引擎特有的組件,因此 binlog
不會像 redo log
同樣先寫入到緩衝池中的 redo log buffer
組件而後再刷回到磁盤中,因此應該是直接寫入磁盤中。內存
binlog 的刷盤策略?it
binlog
也有刷盤策略,那麼就是說,binlog
並不必定是直接寫入磁盤文件中。原理
binlog
的刷盤策略由參數 sync_binlog
參數控制。默認值是0,提交事務時,會將 binlog
寫入 os cache 內存緩存中。可是這樣會出現 MySQL 宕機致使內存緩存中的 binlog
丟失的問題。數據
因此咱們建議將 sync_binlog
的值設置爲1。此時當你提交事務時,會強制將 binlog
寫入磁盤文件中,就不會出現上面數據丟失的狀況了。文件
上面講到,咱們都是建議在事務提交時,強制將 redo log
和 binlog
刷入磁盤文件中,保證事務提交後,不存在日誌丟失的問題。
那麼,這兩個日誌在事務提交時的原理是怎麼樣的呢?
①、首先會將 rodo log buffer
中的 redo log
刷回磁盤文件中,此時磁盤文件有了對應的 redo log
日誌文件;
②、接着,執行器會將 binlog
也寫入到磁盤文件中,此時磁盤文件中也有了對應的 binlog
日誌文件;
③、最後,還會將 binlog
日誌文件的名稱和位置寫入到 redo log
日誌文件中,同時,會在 redo log
日誌文件中加上一個 commit
標記。
binlog
主要用來作數據歸檔的,它是邏輯日誌,主要記錄偏向邏輯性的日誌,相似於「對錶 t 中的 id=1 的一行數據進行了更新操做,更新之後的值是什麼」。
redo log
主要用來作 MySQL 崩潰後數據恢復,它是物理日誌,主要記錄偏向物理性的日誌,相似於「對哪一個數據頁中的哪個記錄作了什麼修改」。
redo log
是 InnoDB 存儲引擎特有的,而 binlog
是 MySQL Server 的組件,因此是全部存儲引擎共享的。
上面也說到 redo log
是 InnoDB 存儲引擎特有的,因此它必定能被保證寫入到磁盤,可是 binlog
倒是 MySQL Server 的組件,因此 InnoDB 存儲引擎不能保證它必定能成功寫入磁盤,因此須要 rodo log
中 commit
標記來代表 binlog
寫入成功了。
那爲何要保證 binlog 成功寫入磁盤呢?
由於須要保證數據的一致性。
咱們假設沒有 commit
標記:
提交事務時,redo log
寫入成功,而 binlog
寫入失敗,可是 InnoDB 存儲引擎並不知道 binlog
是否寫入成功,而後返回成功。當利用 binlog
來作數據歸檔時,例如 MySQL 的主從複製就是利用 binlog
來作的,那此時會由於 binlog
日誌的缺失,而致使主從的數據不一致。
可是若是加入 commit
標記了,只有當 redo log
中有 commit
標記纔算事務提交成功,這樣就能保證兩個日誌文件的一致性了。