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