1. 程式人生 > 實用技巧 >MySQL學習筆記-MySQL的日誌系統

MySQL學習筆記-MySQL的日誌系統

MySQL的日誌系統

更新流程涉及兩個重要的日誌模組

  • redo log(重做日誌)
  • binlog(歸檔日誌)

redo log(InnoDB特有的日誌)

設計的原因

如果每一次的更新操作都寫進磁碟,磁碟需要找到對應的記錄再更新。

整個過程的IO成本,查詢成本很高

實現原理

1.當有一條記錄更新時,InnoDB引擎會先將記錄寫到redo log裡面

2.當MySQL空閒時,才將操作記錄儲存到磁盤裡面

注意

3.如果redo log此時儲存的記錄不多,就先寫進去,空閒時間再儲存到磁碟

4.如果redo log此時已經快滿,就需要停下更新操作(此時就會影響系統的效能了,應儘量避免此類情況的發生),先想redo log一部分記錄儲存到磁碟,再繼續更新操作

設計redo log的技術WAL技術:Write-Ahead Logging

先寫日誌,再寫磁碟

crash-safe

有了redo log,InnoDB可以保證資料庫發生異常重啟時,提交的記錄也不會丟失,此技術稱之為crash-safe

binlog(server層自帶的)

binglog日誌只能用於歸檔,沒有crash-safe能力,這也是redo log出現的原因

redo log日誌與binlog日誌的不同點

1.redo log是InnoDB引擎特有的;binlog是MySQL的Server層實現的,所有引擎都可使用

2.redo log是物理日誌,記錄的是“在某個資料頁上做了什麼修改”;binlog是邏輯日誌,記錄語句的原始邏輯

3.redo log是迴圈寫的,空間固定;binlog可追加寫,不會覆蓋以前的日誌

一個更新語句在MySQL內部的實現

例如:

mysql> create table T(ID int primary key,c int);
mysql> update T set c=c+1 where ID=2;

1.執行器找引擎取ID=2行,ID是主鍵,所以直接主鍵索引查詢。如果ID=2這一行在記憶體中,則直接返回給執行器;如果不在記憶體中,需要從磁碟讀入記憶體,再返回。

2.執行器拿到資料,將這個值+1,得到新的資料,再呼叫引擎介面寫入

3.引擎將新資料寫入記憶體中,同時將操作記錄記錄到redo log中,此值redo log處於prepare狀態(隨時可以提交狀態)

4.執行器生成操作的binlog,並把binlog寫入磁碟(順序寫入,i/o少)

5.執行器呼叫引擎的提交事務介面,將剛寫入的redo log改成提交狀態(commit)更新完成

兩階段提交

原因:

需要日誌將資料庫恢復到半個月任意一秒的狀態

讓臨時庫與與線上庫保持一致

使用兩階段提交的好處

1.先寫redo log後寫binlog時。當redo log寫完,binlog還沒寫,系統崩潰。再重啟時,

系統由redo log與binlog兩個備份恢復的資料會不一致

2.先寫binlog,後寫redo log。如果binlog寫完crash,由於redo log還沒寫,崩潰後這個事務無效,所以系統的值與binlog裡面記錄的不一致

3.使用兩階段提交可以很好的避免上述問題

4.redo log和binlog都可以表示事務的提交狀態,而兩階段提交可以讓這兩個狀態保持邏輯上的一致

redo log保證crash-safe能力的引數

表示每次事務的redo log都直接持久化到磁碟,保證MySQL異常重啟後資料不丟失

innodb_flush_log_at_trx_commit 引數設定為1

表示每次事務的binlog都持久化到磁碟,保證MySQL異常重啟後binlog不丟失

sync_binlog 引數設定為1