首先說下undolog:
undo log的主要作用是用作事務的回滾和實現mvcc功能,因為mvcc的問題,需要對undolog隨機讀
user表中原紀錄為
id | name |
1 | xiaoming |
這個時候執行一個sql update user set name = 'xiaohong' where id = 1; 這個時候生成的undolog是邏輯變更,大概是update user set name = 'xiaoming' where id = 1
undolog用來保證事務的一致性,在事務回滾的時候會查詢對應的undolog,進行回滾。
undolog分為兩種,一種是insert undolog,這種是插入語句對應的的undo log,他不會被作為mvcc,於是在提交之后這個log直接釋放。
還有另外一種就是update undolog 這種是會以用於mvcc的,於是這種undolog 是會用鏈表串起來的,知道沒有開啟的事務早於當前undolog的創建時間,這個時候這個undolog就可以刪除了
redolog
redolog用來保證事務的原子性和持久性
數據庫運行階段不需要讀redolog進行讀取。 所有線程公用一份redolog buffer。 在事務執行期間,redolog是記錄在redolog buffer中的
innodb_flush_log_at_trx_commit參數會決定redo log刷盤的頻率,如果是設置為1,那么每次commit都會刷盤(最好設置成這樣),innodb master會每秒調用 write 寫到文件系統的 page cache,然后調用 fsync 持久化到磁盤。
還有兩種情況是會主動刷盤:
1、redolog buffer占用超過innodb_log_buffer_size的一半,就會write到page cache中
2、事務提交的時候會把redo log buffer持久化到磁盤
因為兩階段提交是 redo log 先 prepare, 再寫 binlog,最后再把 redo log commit
所以redo log 在 prepare階段 就要先write並fsync
redolog buffer在提交的時候里面可能包含了多個事務的redolog,所以一次性fsync的事務越多越好,那么就有了一個優化
這里的紅色塊是在一個隊列中,頭trx是事務,然后會遍歷redolog buffer進行write,然后由leader進行fsync
我們理解的事務兩階段提交是 redolog prepare -> binlog 寫入磁盤 -> redolog commit
redolog prepare 的時候需要寫redolog,其實分為兩步 redolog wirte和redolog fsync
binlog的寫盤也是分為兩步 binlog wirte 和 binlog fsync
所以最終你以為的事務提交過程是 redolog wirte -> redolog fsync -> binlog wirte -> binlog fsync
但是實際上這里做了一個優化,就是redolog希望盡可能晚的進行組提交, 就可以減少fsync的次數
binlog 其實是數據庫server層的日志,一般用作主從同步和數據恢復,數據格式有statement、row、還有mixed
statement是sql格式的,row記錄了行的變更(從什么到什么),mixed是這兩種的混合形式
binlog是在兩階段提交 preparre 和 commit之間,也是要先write到page cache(文件系統緩沖區),然后調用fsync進行刷盤