MySQL,bin log、redo log

首先,我們先來看看一次查詢/更新語句流程圖

mysql查詢/更新流程圖


本文會將重點放在執行器<->存儲引擎之間的交互

 

mysql不是每次數據更改都立刻寫到磁盤,而是會先將修改後的結果暫存在內存中,當一段時間後,再一次性將多個修改寫到磁盤上,減少磁盤io成本,同時提高操作速度。

 

MySQL通過WAL(write-ahead logging)技術保證事務


在同一個事務中,每當數據庫進行修改數據操作時,將修改結果更新到內存後,會在redo log添加一行記錄記錄“需要在哪個數據頁上做什麼修改”,並將該記錄狀態置爲prepare,等到commit提交事務後,會將此次事務中在redo log添加的記錄的狀態都置爲commit狀態,之後將修改落盤時,會將redo log中狀態爲commit的記錄的修改都寫入磁盤。

 

過程如下圖

更新流程

 

redo log記錄方式


redolog的大小是固定的,在mysql中可以通過修改配置參數innodb_log_files_in_group和innodb_log_file_size配置日誌文件數量和每個日誌文件大小,redolog採用循環寫的方式記錄,當寫到結尾時,會回到開頭循環寫日誌。

 

如下圖

redolog記錄方式


write pos表示日誌當前記錄的位置,當ib_logfile_4寫滿後,會從ib_logfile_1從頭開始記錄;check point表示將日誌記錄的修改寫進磁盤,完成數據落盤,數據落盤後checkpoint會將日誌上的相關記錄擦除掉,即write pos->checkpoint之間的部分是redo log空着的部分,用於記錄新的記錄,checkpoint->write pos之間是redo log待落盤的數據修改記錄。關注公衆號Java面試那些事兒,回覆關鍵字面試,領取大廠最新面試題。當writepos追上checkpoint時,得先停下記錄,先推動checkpoint向前移動,空出位置記錄新的日誌。


有了redo log,當數據庫發生宕機重啓後,可通過redo log將未落盤的數據恢復,即保證已經提交的事務記錄不會丟失。

 

有了redo log,爲啥還需要binlog呢?

 

1、redo log的大小是固定的,日誌上的記錄修改落盤後,日誌會被覆蓋掉,無法用於數據回滾/數據恢復等操作。
2、redo log是innodb引擎層實現的,並不是所有引擎都有。

 

基於以上,binlog必不可少。

 

1、binlog是server層實現的,意味着所有引擎都可以使用binlog日誌

2、binlog通過追加的方式寫入的,可通過配置參數max_binlog_size設置每個binlog文件的大小,當文件大小大於給定值後,日誌會發生滾動,之後的日誌記錄到新的文件上。
3、binlog有兩種記錄模式,statement格式的話是記sql語句, row格式會記錄行的內容,記兩條,更新前和更新後都有。

 

binlog和redo log必須保持一致,不允許出現binlog有記錄但redolog沒有的情況,反之亦然。之前說過在一個事務中,redolog有prepare和commit兩種狀態,所以,在redolog狀態爲prepare時記錄binlog可保證兩日誌的記錄一致,下圖列出各種情況來說明。

 

 

現在我們再來看看整個完整的流程圖

更新流程


相關參數設置建議:

 

1、innodb_flush_log_at_trx_commit:設置爲1,表示每次事務的redolog都直接持久化到磁盤(注意是這裏指的是redolog日誌本身落盤),保證mysql重啓後數據不丟失。
2、sync_binlog:設置爲1,表示每次事務的binlog都直接持久化到磁盤(注意是這裏指的是binlog日誌本身落盤),保證mysql重啓後binlog記錄是完整的。

 

作者:Mr林_月生

來源:https://www.jianshu.com/p/4bcfffb27ed5

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章