MySQL事務提交過程(二)

來源:互聯網
上載者:User

標籤:

上一篇文章我們介紹了在關閉binlog的情況下,事務提交的大概流程。之所以關閉binlog,是因為開啟binlog後事務提交流程會變成兩階段交易認可,這裡的兩階段交易認可並不涉及分散式交易,當然mysql把它稱之為內部xa事務(Distributed Transactions),與之對應的還有一個外部xa事務。

這裡所謂的兩階段交易認可分別是prepare階段和commit階段。

內部xa事務主要是mysql內部為了保證binlog與redo log之間資料的一致性而存在的,這也是由其架構決定的(binlog在mysql層,而redo log 在儲存引擎層);

外部xa事務則是指支援多執行個體分散式交易,這個才算是真正的分散式交易。

既然是xa事務,必然涉及到兩階段交易認可,對於內部xa而言,同樣存在著提交的兩個階段。

下文會結合源碼詳細解讀內部xa的兩階段交易認可過程,以及各種情況下,mysqld crash後,mysql如何恢複來保證事務的一致性。

   

測試環境

OS:WIN7

ENGINE:

DB:

   

設定檔參數:

log-bin=D:\mysql\log\5-6-21\mysql-binbinlog_format=ROWset autocommit=0;innodb_support_xa=1sync_binlog=1;innodb_flush_log_at_trx_commit=1;

【innodb_flush_log_at_trx_commit=1,sync_binlog=1

不同的模式區別在於,寫檔案調用write和落盤fsync調用的頻率不同,所導致的後果是mysqld 或 os crash後,不嚴格的設定可能會丟失事務的更新。

雙一模式是最嚴格的模式,這種設定情況下,單機在任何情況下不會丟失事務更新。】

   

測試條件

set autocommit=0;
-- ------------------------------ Table structure for `user`-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (`id` int(20) NOT NULL,`account` varchar(20) NOT NULL,`name` varchar(20) NOT NULL,PRIMARY KEY (`id`),KEY `id` (`id`) USING BTREE,KEY `name` (`name`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;

   

測試語句

insert into user values(1, ‘sanzhang‘, ‘張三‘);
commit;

   

prepare階段:

    1.設定undo state=TRX_UNDO_PREPARED; //trx_undo_set_state_at_prepare調用

    2.刷事務更新產生的redo日誌;【步驟1產生的redo日誌也會刷入】

MYSQL_BIN_LOG::prepareha_prepare_low    {engine:binlog_prepareinnobase_xa_preparemysql:trx_prepare_for_mysql{                1.trx_undo_set_state_at_prepare    //設定undo段的標記為TRX_UNDO_PREPARED                2.設定事務狀態為TRX_STATE_PREPARED                3.trx_flush_log_if_needed  //將產生的redolog刷入磁碟            }     }

     

commit階段:

   1.將事務產生的binlog寫入檔案,刷入磁碟;

   2.設定undo頁的狀態,置為TRX_UNDO_TO_FREE或TRX_UNDO_TO_PURGE;  // trx_undo_set_state_at_finish調用

   3.記錄事務對應的binlog位移,寫入系統資料表空間; //trx_sys_update_mysql_binlog_offset調用

MYSQL_BIN_LOG::commit    ordered_commit   {1.FLUSH_STAGE        flush_cache_to_file  //  刷binlog2.SYNC_STAGE        sync_binlog_file    //Call fsync() to sync the file to disk.3.COMMIT_STAGE        ha_commit_low        {            binlog_commit            innobase_commit                   trx_commit(trx)                 {                    trx_write_serialisation_history(trx, mtr);  //更新binlog位點,設定undo狀態                    trx_commit_in_memory(trx, lsn); //釋放鎖資源,清理儲存點列表,清理復原段                }                }     }

   

在任何情況下(機器掉電)mysqld crash或者os crash,MySQL仍然能保證資料庫的一致性。資料的一致性是如何做到的哪?正是二階段提交。

我們結合幾種情境來分析下二階段提交是如何做到的:

1.prepare階段,redo log落盤前,mysqld crash

2.prepare階段,redo log落盤後,binlog落盤前,mysqld crash

3.commit階段,binlog落盤後,mysqld crash

對於第一種情況,由於redo沒有落盤,毫無疑問,事務的更新肯定沒有寫入磁碟,資料庫的一致性受影響;

對於第二種情況,這時候redo log寫入完成,但binlog還未寫入,事務處於TRX_STATE_PREPARED狀態,這是提交還是復原呢?

對於第三種情況,此時,redo log和binlog都已經落盤,只是undo狀態沒有更新,雖然redo log和binlog已經一致了,事務是否應該提交?

   

我們結合mysqld異常重啟後的執行邏輯以及關鍵的原始碼。

對於第三種情況,我們可以搜集到未提交事務的binlog event,所以需要提交;

對於第二種情況,由於binlog未寫入,需要通過執行復原操作來保證資料庫的一致性。

   

異常重啟後,如何判斷事務該提交還是復原

1.讀binlog日誌,擷取崩潰時沒有提交的event;  //info->commit_list中含有該元素

2.若存在,則對應的事務要提交;否則需要復原。

   

判斷事務提交或復原源碼如下:

   

上面討論了兩階段交易認可的基本流程,以及伺服器異常crash後,mysql如何重啟恢複保證binlog和資料的一致性。

簡而言之,對於異常的xa事務,若binlog已落盤,則事務應該提交;binlog未落盤,則事務就應該復原。

   

//異常重啟後,復原流程

innobase_rollback_by_xidrollback_by_xidtrx_rollback_resurrected    trx_rollback_active        row_undo        {            //從復原頁擷取undo記錄            //分析undo記錄類型            if (insert)                row_undo_ins            else                row_undo_mod        }

 

   

//異常重啟後,提交流程

commit_by_xidtrx_commit_for_mysql

   

//寫binlog介面

handler.cc:binlog_log_rowsql/binlog.cc:commitmysys/my_sync:my_syncsql/binlog.cc:sync_binlog_filehandler/ha_innodb.cc:innobase_xa_prepare

   

binlog記錄檔是為瞭解決MySQL主從複製功能而引入的一份新記錄檔,它包含了引發資料變更的事件記錄集合。

從程式庫要求主庫發送 binlog 並通過日誌事件還原資料寫入從庫,所以從庫的資料來源為 binlog。

這樣 MySQL 主庫只需做到 binlog 與本機資料一致就可以保證主從庫資料一致(暫且忽略網路傳輸引發的主從不一致)。

   

參考

   1、《高效能MySQL》

   2、mysql 事務提交過程

MySQL事務提交過程(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.