mysql 5 6 binlog組提交實現原理

2021-07-09 07:46:51 字數 4364 閱讀 7212

原文:

redo

組提交

redo

提交流程大致如下

lock log->mutex

write redo log buffer to disk

unlock log->mutex

fsync

fsync

寫磁碟耗時較長且不占用

log->mutex

,也就是其執行期間其他執行緒可以

write log buffer;

假定一次

fsync

需要10ms

,而寫buffer

只需要1ms

,則fsync

執行期間最多可以有10條

redo record

寫入buffer

,則下次呼叫

fsync

時可一次性寫

10條記錄;

binlog

組提交mysql 

從5.0 

開始支援

2pc,在**實現時為了保證

binlog

中的事務順序和事務

commit

順序一致,放棄了

group commit。

如果binlog

順序不一致,那麼備庫就無法確保和主庫有一致的資料。這個問題直到

mysql 5.5 

才開始部分修復,到

mysql 5.6 

完全修復。

mysql 5.5 

中,只有當

sync_binlog = 0 

時,才能使用

group commit

,在mysql 5.6

中都可以進行

group commit

。2pc

下的事務提交流程

1. prepare innodb:

a) write prepare record to innodb's log buffer

b) sync log file to disk  -- redo

組提交

c) take prepare_commit_mutex

2. "prepare" binary log:

a) write transaction to binary log

b) sync binary log based on sync_binlog

3. commit innodb:

a) write commit record to log

b) release prepare_commit_mutex

c) sync log file to disk

d) innodb locks are released

4. "commit" binary log:

a) nothing necessary to do here.

不足為保證binlog

按順序寫,

prepare redo

階段獲取

prepare_commit_mutex

,直到sync redo

前才釋放;一次只能有乙個事務可獲取該

mutex

,阻礙了

group commit;

另外,一次完整的事務提交需要呼叫3次

fsync

,效率很低; 改進

1 減少

fsync

crash recovery

時先檢視

redo log

,找出prepared

但沒有commited

或aborted

的事務列表,然後檢查

binlog

,如果binlog

記錄了該事務,則將其

commit

否則rollback;

由此可見,事務恢復時取決於

binlog

是否有記錄,因此

commit innodb

時無須呼叫立即

fsync(

此時binlog

已寫入,就算

crash

也能保證事務提交);

2 細化

binlog commit

**,實現組提交 在

oracle mysql 5.6.15

中,binlog group commit

模組被重寫,這個過程分為3個

stage

:flush/sync/commit;

5.6的

2pc提交流程如下

1. ask binary log (i.e. coordinator to prepare

a) request to release locks earlier

b) prepare innodb (callback to (2.a))

2. prepare innodb:

a) write prepare record to innodb log buffer

b) sync log file to disk

3. ask binary log (i.e. coordinator) to commit

a) lock access to flush stage

b) write a set of transactions to the binary log

c) unlock access to flush stage

d) lock access to sync stage

e) flush the binary log to disk

f) unlock access to sync stage

g) lock access to commit stage

h) commit innodb (callback to (4.a))

i) unlock access to commit stage

4. commit innodb

a) write a commit record to innodb log buffer

binlog

提交被細化為

3個處理階段,每一階段都有

lock保護(

此時redo

已經呼叫

fsync

,事務尚未提交);

這3個階段負責批量讀取

binlog

並呼叫fsync

,而後以同樣順序提交事務(可選

);第乙個進入處理階段的事務擔當

leader

的角色,剩餘的為

follower

,後者釋放所有的

latch

並等待,直至

leader

完成commit;

leader

獲取所有排隊等待的事務並處理,進入下乙個處理階段時,如果隊列為空則仍是

leader

,否則降級為

follower;

1. flush stage

leader

會不斷讀取

flush queue

直到隊列為空或者超時,這樣允許處理過程中新加入的事務也能得到及時處理;

leader

將排隊的事務寫入

binlog buffer

,當隊列為空時則進入下一階段;

超時機制避免了事務長時間等待,

2. sync stage 呼叫

fsyc

,一次重新整理多個事務;

3. commit stage

提交事務,保證所有事務提交順序同寫入

binlog

一致(innodb hot backup)

;為了提公升效能,也可選擇不按次序提交;

**實現

binlog

原本實現了

handlerton

介面,包括

commit()/rollback()

等方法,

5.6引入新機制

public class mysql_bin_log: public tc_log ;

int mysql_bin_log::commit(thd *thd, bool all)

int mysql_bin_log::batch_commit(thd* thd, bool all)

else

--通知follower

,要麼提交事務

(opt_binlog_order_commits=false)

要麼通知客戶端;

stage_manager.signal_done(final_queue);

return finish_commit(thd); }

參考資料

MySQL開啟binlog日誌

mysql開啟binlog日誌很簡單,只需要找到配置檔案,在配置檔案中的 mysqld 配置段新增下面一句話就可以了 log bin mysql bin 這樣就開啟了mysql的binlog日誌。使用下面的sql語句在mysql的客戶端可以檢視binlog日誌是否開啟 show master log...

mysql 匯出binlog日誌

首先你得開啟了mysql的bin log.找到你的mysqlbinlog。執行 find name mysqlbinlog 檢視mysql server上的二進位制日誌 mysql showbinarylogs 將binlog檔案匯出為sql檔案 usr local src mysql 5.7.10...

Mysql開啟binlog 實踐

mysql binlog是mysql資料庫的二進位制日誌,用於記錄使用者對資料庫操作的sql語句 除了資料查詢語句 資訊。binlog的格式也有三種 statement row mixed 我使用的是用docker安裝的mysql,所以需要提前掛載好配置檔案。開啟binlog方法 1 找到 my,c...