天天看點

MySQL源碼學習:InnoDB關于group commit的簡單QA

    前天同僚問了個問題,今天又再翻了下group commit。關于這個話題kristian nielsen有一個很詳盡的系列文章(http://kristiannielsen.livejournal.com/12254.html), 有四個頁面,文中有連結。這裡列出一些細節,主要是對上面文章補充一下。

q:什麼是group commit。

a:1) 簡單說就是:好幾個線程寫檔案,然後一個線程fsync;

2) 隻有事務日志(ib_logfile)用到;

3) 注意是多個線程(多使用者)。一個線程在一個事務過程中若出現多次寫事務日志,是不能一起送出的。

q: 既然是多個線程,那怎麼決定由哪個線程去”commit”

a:其實每個線程都會試着去fsync。成功fsync之後線程會修改log_sys->written_to_all_lsn。 另外一個線程在fsync之前若判斷log_sys->written_to_all_lsn大于自己的lsn,說明自己要作的事兒已經被别的線程做掉了,直接傳回(group commit獲益)。

q:group commit怎麼保證事務日志順序和bin-log順序一緻。

a:這個問題是在kristian nielsen那篇文章中糾結最多的。目前的做法,是在寫binlog前的prepare階段加了個鎖,這個鎖直到binlog寫完,然後将新的binlog位置填到trx->mysql_log_offset才解開。是以兩個日志上的事務順序是保證一緻的。

在這個機制下,binlog是無法實作group commit的,是以直到最新的5.6版本中的log_xid函數的注釋中依舊寫着”todo: group commit”。

(補充說明:percona 5.5.18版本以後已經有binlog group commit的功能)

繼續閱讀