MySQL系列:innodb源碼分析之mini transaction,mysqlinnodb

來源:互聯網
上載者:User

MySQL系列:innodb源碼分析之mini transaction,mysqlinnodb

    日誌是innodb一個非常重要的模組,在innodb中有兩類日誌:redo log和undo log。其中redolog日誌是用來做資料異常恢複和資料庫重啟時頁資料同步恢複的,redo log是建立在在mini transaction基礎上。資料庫在執行事務時,通過minitransaction產生redo log來保證事務的持久性。

1.mini transaction三個協議

        mini-transcation是用來實現innodb的物理邏輯日誌的寫入和頁恢複的,通過mini-transcation來保證並發事務操作和資料庫異常是頁的一致性。為了得到頁的一致性,mini-transaction遵循以下三個協議:

        1. The FIX Rules

      2. Write-Ahead Log

      3. Force-log-at-commit

1.1The FIX Rules

    The FIX Rules規定如下:

              修改一個頁需要獲得該頁的x-latch

              訪問一個頁是需要獲得該頁的s-latch或者x-latch

              持有該頁的latch直到修改或者訪問該頁的操作完成

1.2Write-Ahead Log

       Write-Ahead Log的意思就是如果一個頁操作在寫入到持久裝置時,必須記憶體中相對應的日誌寫入到持久化裝置中。每個頁有一個LSN,每次頁修改需要維護這個LSN,當一個頁需要寫入到持久化裝置時,要求記憶體中小於該頁LSN的日誌先寫入到持久化裝置中。日誌寫完後,先Fixed這個頁的latch,再將記憶體中的頁刷盤。完成刷盤後,釋放頁latch。這裡遵循The FIX Rules協議。

1.3 Force-log-at-commit

       一個事務可以同時修改了多個頁,Write-AheadLog單個資料頁的一致性,無法保證事務的持久性。Force -log-at-commit要求當一個事務提交時,其產生所有的mini-transaction日誌必須刷到持久裝置中。這樣即使在頁資料刷盤的時候宕機,也可以通過日誌進行redo恢複。

2 mini-transaction的日誌實現

       innodb是採用mini-transaction來構建操作的物理邏輯日誌的,在事務執行的時候,會通過mtr來保證頁的資料一致性和持久性。mini-transaction是通過一個mtr_t的結構來實現mini-transaction的三個協議。mtr_t的定義如下:

typedef struct mtr_struct    {         ulint state;                      /*mtr的狀態,MTR_ACTIVE、MTR_COMMITING、MTR_COMMITTED*/         dyn_array_t memo;        /*正在持有的latch列表*/         dyn_array_t log;             /*mtr產生的日誌資料*/         ibool modifications;     /*是否修改了頁*/         ulint n_log_recs;            /*log操作頁的個數*/         ulint log_mode;             /*log操作模式,MTR_LOG_ALL、MTR_LOG_NONE、MTR_LOG_SHORT_INSERTS*/         dulint start_lsn;              /*mtr起始的LSN*/         dulint  end_lsn;             /*mtr結束的LSN*/         ulint  magic_n;             /*魔法字*/    }mtr_t;

其中成員memo是個latch持有狀態的數組列表,採用的是dyn_array_t的動態記憶體結構來儲存的,每個單中繼存放區的是mtr_memo_slot_t這樣的結構。定義如下:
      

typedef struct mtr_memo_slot_struct        {             ulint type;            /*latch的類型值*/             void* object;        /*latch物件控點,可以是rw_lock_t或者buf_block_t*/        }mtr_memo_slot_t;

latch類型如下:
    MTR_MEMO_PAGE_S_FIX         /*rw_locks-latch*/
    MTR_MEMO_PAGE_X_FIX         /*rw_lockx-latch*/
    MTR_MEMO_BUF_FIX               /*buf_block_t*/
    MTR_MEMO_S_LOCK               /*rw_lock s-latch*/
    MTR_MEMO_X_LOCK               /*rw_lock x-latch*/

 

memo的latch管理介面
    mtr_memo_push                                       獲得一個latch,並將狀態資訊存入mtr memo當中
    mtr_release_s_latch_at_savepoint       釋放memo位移savepoint的slot鎖狀態
    mtr_memo_contains                          判斷鎖對象是否在memo當中
    mtr_memo_slot_release                    釋放slot鎖的控制權
    mtr_memo_pop_all                            釋放所有memo中的鎖的控制權

mt_t中的log成員是也是一個dyn_array_t動態結構的記憶體,用來儲存mtr產生的日誌資訊。日誌的寫入是通過mtr0log.h來寫入的。這裡指的一提的是日誌格式,日誌格式是有日誌頭和日誌體組成,日誌頭資訊是由type、space和page no組成,由mlog_write_initial_log_record_fast函數寫入到mtr_t的log中的。以下是一個比較具體的:

      

log body的資料寫入是通過mtr0log.h中的日誌寫入方法進行寫入的。每寫入一跳動作記錄,n_log_recs會加1.

標識modifications是標識是否有page的資料改動,如果有,在mtr_commit調用時會先將mtr->log刷盤,然後釋放mtr所有的所控制權。日誌會一定會在mtr結束時刷盤,這符合Force-log-at-commit的規定。日誌寫入調用的是log_write_low這個函數。

2.1 mtr_t的記憶體結構關係圖

3 總結mini transaction是innodb對ACID中的持久性的最小保證單元,所有涉及到事務執行、頁資料刷盤、redo log資料恢複等都需要進行mini transaction的構造和執行。幾乎所有的模組都涉及到mini transaction,例如:btree、page、事務、inser tbuffer、redo-log等,d對mini transcaion的理解不能孤立的去看原始碼,應該結合redo log、page相關的代碼瞭解。它是理解innodb工作原理的基石。


 

 

 

 



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.