Mysql什麼版本支援組提交 mysql組提交

2021-10-18 08:49:20 字數 2770 閱讀 9597

當mysql開啟binlog日誌時,會存在乙個內部xa的問題:事務在儲存引擎層redo log的寫入和binlog的寫入一致性問題。

mysql通過兩階段提交很好的解決了redo log和binlog一致性問題:

第一階段:innodb prepare, 持有prepare_commit_mutex,redo log持久化到磁碟(flush/sync redolog),並將回滾段設定為prepare狀態。

第二階段:分為兩步。

a. flush/sync binlog

b. commit(寫入commit標記,釋放prepare_commit_mutex,並釋放回滾段)

事務的崩潰恢復過程如下:

1. 事務恢復時,掃瞄最後乙個binlog,提取出其中的xid

2. xid也會寫到redo中,重做檢查點後的所有事務,包括未提交的事務和已回滾的事務,讀取事務的undo段資訊,蒐集處於prepare階段的事務鍊錶,將redo中prepared狀態的xid與binlog中的xid做比較,如果在binlog中存在,則提交;否則回滾。

為什麼只掃瞄最後乙個binlog?

因為binlog rotate的binlog檔案中對應的事務一定是已經提交的

group commit:

上面的整個過程,通過持有 prepare_commit_mutex來保證redolog的寫入和binlog的寫入完全一致,會導致group commit無法生效。

在mysql56中,同時支援了redolog 和 binlog的組提交,其提交流程如下:

第一階段: innodb prepare(redo group commit)

在innodb中,每條redolog都有自己的lsn,這是乙個單調遞增的值。每個事務的更新操作都會包含一條或者多條redo log, 各個事務在將redo log寫入 log_sys_buffer(通過log_sys mutex保護)時,都會獲取當前事務最大的lsn。那麼假設三個事務 tx1, tx2, tx3的最大lsn分別為 lsn1 < lsn2 < lsn3時,他們同時進行提交,如果tx3獲取到了 log_mutex, 那麼他會將小於lsn3之前的redo log一起落盤,這樣 tx1, tx2不用再次請求磁碟io。同時,如果存在tx0的lsn0 < lsn3,lsn0也會落盤,即使tx0還沒有提交。

1. 獲取 log mutex

2. 如果 flushed_to_disk_lsn >= lsn, 表示日誌已經被刷盤,跳轉 5

3. 如果 current_flush_lsn >= lsn, 表示日誌正在刷盤中,跳轉 5 後進入等待狀態

4. 將小於 lsn 的日誌刷盤 (flush and sync)

5. 退出 log_mutex

第二階段: binlog group commit的基本思想是引入佇列機制,保證 innodb commit 的順序與 binlog落盤的順序一致,並將事務分組,組內的 binlog刷盤動作交給乙個事務進行,實現組提交的目的。佇列中的第乙個事務稱為 leader, 其他事務稱為 follower。所有的事情交給 leader 去做。: flush stage, sync stage, commit stage

flush stage:

將每個事務的 binlog 寫入記憶體

1. 持有 lock_log mutex [leader持有,follwer等待]

2. 獲取佇列中的一組 binlog(佇列中的所有事務)

3. 將 binlog buffer 到 i/o cache

4. 通知 dump執行緒 dump binlog [sync_binlog != 1]

sync stage:

將記憶體中的二進位制日誌重新整理到磁碟, 若佇列中有多個事務,那麼僅一次 fsync 操作就完成了二進位制日誌的寫入,這就是 blgc。

1. 釋放 lock_log mutex, 持有 lock_sync mutex[leader持有,follower等待]

2. 將一組 binlog 落盤(sync操作,最耗時,假設 sync_binlog 為 1)

3. 通知 dump執行緒 dump binlog [sync_binlog = 1]

commit stage:

leader根據順序呼叫儲存引擎層的提交

1. 釋放 lock_sync mutex, 持有 lock_commit mutex[ leader持有,follower等待]

2. 遍歷佇列中的事務,逐一進行 innodb commit.

3. 釋放 lock_commit mutex

4. 喚醒佇列中等待的執行緒。

redo group commit優化

每個事務提交時,都會觸發一次redo flush/sync動作,由於磁碟讀寫比較慢,因此很影響系統的吞吐量。

mysql57中,做了針對redo group commit的優化。將 redo log的write/sync延遲到了binlog group commit的 flush stage之後,sync binlog之前。

通過延遲寫redo log的方式,顯式的為redo log做了一次組寫入,並減少了(redo log) log_sys->mutex的競爭。

第一階段:innodb prepare

1. 記錄當前的lsn到thd中

第二階段:binlog group commit

1. 進入binlog group commit的flush階段;同時,leader搜尋佇列,算出thd中最大的lsn

2. 將innodb的redo log flush/sync到指定lsn

3. sync binlog

4. commit

參考

mysql5 7組提交 mysql組提交

當mysql開啟binlog日誌時,會存在乙個內部xa的問題 事務在儲存引擎層redo log的寫入和binlog的寫入一致性問題。mysql通過兩階段提交很好的解決了redo log和binlog一致性問題 第一階段 innodb prepare,持有prepare commit mutex,re...

mysql 5 6 binlog組提交實現原理

原文 redo 組提交 redo 提交流程大致如下 lock log mutex write redo log buffer to disk unlock log mutex fsync fsync 寫磁碟耗時較長且不占用 log mutex 也就是其執行期間其他執行緒可以 write log bu...

mysql版本查詢命令是什麼

mysql版本查詢命令有 1 輸入 select version 命令,按回車鍵,即可檢視當前mysql版本 2 輸入 status 命令,按回車鍵,即可檢視當前mysql版本。本教程操作環境 windows7系統 mysql8.0版本 dell g3電腦。在我們的電腦上開啟mysql控制台,輸入密...