中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

【MYSQL】兩階段提交及相關參數介紹

發布時間:2020-08-11 11:23:48 來源:ITPUB博客 閱讀:299 作者:ai3707 欄目:MySQL數據庫
    由于Mysql的事務日志包含二進制日志和存儲引擎日志,當發生崩潰恢復時,MySQL主節點通過redo log進行恢復,而在主從復制的環境下,slaver節點是依據于主節點的binlog進行同步數據的;這樣的架構于是對mysql的二進制日志和redo log,就有兩個基本要求:第一,保證binlog里面存在的事務一定在redo log里面存在,也就是binlog里不會比redo log多事務(可以少,因為redo log里面記錄的事務可能有部分沒有commit,這些事務最終可能會被rollback)。  2、順序一致,這也是很重要的一點,假設兩者記錄的事務順序不一致,那么會出現類似于主庫事務執行的順序是ta, tb, tc,td,但是binlog里面記錄的是ta,tc, tb, td,binlog復制到從庫后導致主從的數據不一致。為了達到上面說的兩點,mysql是怎么來實現的呢?沒錯,答案是內部xa事務(核心是2pc)

一、二階段事務提交流程:

   【MYSQL】兩階段提交及相關參數介紹

    (1)先調用binglog_hton和innobase_hton的prepare方法完成第一階段,binlog_hton的papare方法實際上什么也沒做,innodb的prepare將事務狀態設為TRX_PREPARED,并將redo log刷磁盤
    (2)如果事務涉及的所有存儲引擎的prepare都執行成功,則調用TC_LOG_BINLOG::log_xid將SQL語句寫到binlog,此時,事務已經鐵定要提交了。否則,調用ha_rollback_trans回滾事務,而SQL語句實際上也不會寫到binlog。
    (3)最后,調用引擎的commit完成事務的提交。實際上binlog_hton->commit什么也不會做(因為(2)已經將binlog寫入磁盤),innobase_hton->commit則清除undo信息,刷redo日志,將事務設為TRX_NOT_STARTED狀態

二、事務恢復流程:

    Innodb在恢復的時候,不同狀態的事務,會進行不同的處理(見trx_rollback_or_clean_all_without_sess函數):

<1>對于TRX_COMMITTED_IN_MEMORY的事務,清除回滾段,然后將事務設為TRX_NOT_STARTED;

<2>對于TRX_NOT_STARTED的事務,表示事務已經提交,跳過;

<3>對于TRX_PREPARED的事務,要根據binlog來決定事務的命運,暫時跳過;

<4>對于TRX_ACTIVE的事務,回滾。

    簡單來講,當發生崩潰恢復時,數據庫根據redo log進行數據恢復,逐個查看每條redo的事務狀態,如果根據上圖流程,已進行到TRX_NOT_STARTED階段,也就是存儲引擎commit階段,那么說明redo log和bin log是一致的,正常根據redo進行恢復即可;事務狀態為TRX_ACTIVE,不用說了,都沒寫到binlog中,直接回滾;但如果事務狀態為TRX_PREPARED,就要分兩種情況了,要先檢查binlog是否已寫入成功?如果沒寫入成功,那么就算是TRX_PREPARED狀態,也要回滾。如果寫入成功了,那么就進行最后一步,調用存儲引擎commit,更改事務狀態為TRX_NOT_STARTED,也就是真正提交狀態,可以用作數據恢復。

    從以上分析可以看出,寫binlog是一定已經提交的數據,只要寫了binlog,事務是鐵定要提交成功的。因為主從復制環境下,寫了binlog就可能直接傳輸到從節點應用了,所以兩階段提交很好的保持數據一致性和順序性

三、相關參數介紹:

1、innodb_support_xa
用于控制innodb是否支持XA事務的2PC,默認是TRUE。如果關閉,則innodb在prepare階段就什么也不做;這可能會導致binlog的順序與innodb提交的順序不一致(比如A事務比B事務先寫binlog,但是在innodb內部卻可能A事務比B事務后提交),這會導致在恢復或者slave產生不同的數據。
2、sync_binlog
Mysql在提交事務時調用MYSQL_LOG::write完成寫binlog,并根據sync_binlog決定是否進行刷盤。默認值是0,即不刷盤,從而把控制權讓給OS。如果設為1,則每次提交事務,就會進行一次刷盤;這對性能有影響(5.6已經支持binlog group),所以很多人將其設置為100。
3、innodb_flush_log_at_trx_commit
   innodb_flush_log_at_trx_commit有0、1、2三個值分別代表不同的使redo log落地策略。0表示每秒進行一次flush,但是每次事務commit不進行任何操作(每秒調用fsync使數據落地到磁盤,不過這里需要注意如果底層存儲有cache,比如raid cache,那么這時也不會真正落地,但是由于一般raid卡都帶有備用電源,所以一般都認為此時數據是安全的)。1代表每次事務提交都會進行flush,這是最安全的模式。2表示每秒flush,每次事務提交時不flush,而是調用write將redo log buffer里面的redo log刷到os page cache。
   那現在來比較三種策略的優劣勢:1由于每次事務commit都會是redo log落地所以是最安全的,但是由于fsync的次數增多導致性能下降比較厲害。0表示每秒flush,每次事務提交不進行任何操作,所以mysql crash或者os crash時會丟失一秒的事務。2相對于0來說了多了每次事務commit時會有一次write操作,此時數據雖然沒有落地到磁盤但是只要沒有 os crash,即使mysql crash,那么事務是不會丟失的。2相對于0來說會稍微安全一點點。

       上面3個參數不同的值會帶來不同的效果。三者都設置為1(TRUE),數據才能真正安全。sync_binlog非1,可能導致binlog丟失(OS掛掉),從而與innodb層面的數據不一致。innodb_flush_log_at_trx_commit非1,可能會導致innodb層面的數據丟失(OS掛掉),從而與binlog不一致

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

广丰县| 承德县| 庆元县| 连平县| 江西省| 西和县| 娄底市| 磴口县| 鹤山市| 清苑县| 武隆县| 屯门区| 铜鼓县| 宾阳县| 绵阳市| 房产| 大洼县| 湖南省| 临夏县| 泊头市| 乌兰察布市| 河曲县| 铜陵市| 高淳县| 山阴县| 称多县| 广元市| 宁化县| 万全县| 泾阳县| 长沙市| 普兰店市| 双辽市| 两当县| 蒙山县| 平顶山市| 五莲县| 吐鲁番市| 宣汉县| 襄城县| 青海省|