MySql事務(wù)處理_第1頁
MySql事務(wù)處理_第2頁
MySql事務(wù)處理_第3頁
MySql事務(wù)處理_第4頁
MySql事務(wù)處理_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、什么是事務(wù)事務(wù)就是一段sql 語句的批處理,但是這個批處理是一個atom(原子),不可分割,要么都執(zhí)行,要么回滾(rollback)都不執(zhí)行。(保證數(shù)據(jù)操作的安全性)為什么出現(xiàn)這種技術(shù)為什么要使用事務(wù)這個技術(shù)呢? 現(xiàn)在的很多軟件都是多用戶,多程序,多線程的,對同一個表可能同時有很多人在用,為保持數(shù)據(jù)的一致性,所以提出了事務(wù)的概念。這樣很抽象,舉個例子-口述。如何使用事務(wù)(1)只有InnoDB /BDB的之類的transaction_safe table(commit-or-rollback,如果是安全的) 才能支持。默認的engine 

2、;MyISAM 是不支持事務(wù)的。建立InnoDB 表:Create table . type=InnoDB;  Alter table table_name type=InnoDB;(如何查看已有表的類型: show create table table_name)這樣我們就可以在InnoDB 表上進行事務(wù)操作了?。?)啟動事務(wù)的方法-2種:1、(推薦)begin ,rollback,commit .當然有的人用begin /

3、begin work .推薦用START TRANSACTION 是SQL-99標準啟動一個事務(wù)。    start transaction;update from account set money=money-100 where name='a'update from account set money=money+100 where name='b'

4、commit;解釋: 這樣start transaction 手動開啟事務(wù),commit 手動關(guān)閉事務(wù)。2、默認的時候autocommit=1 自動提交是開啟的,所以你可以理解為每條語句一輸入到mysql就commit 了。當你 set autocommit=0 時候,你可以這樣:update from account set money=money-100 where name='a'update from 

5、account set money=money+100 where name='b'commit;/ 默認都不提交,只有手動鍵入commit 時候才上述都提交。但注意當你用 set autocommit=0 的時候,你以后所有的SQL都將做為事務(wù)處理,直到你用commit確認或rollback結(jié)束,注意當你結(jié)束這個事務(wù)的同時也開啟了個新的事務(wù)事務(wù)是必須滿足4個條件(ACID)      原子性(Autmic):事務(wù)在執(zhí)行性,要做到“要么不做,要么全做!”,就是說不允許事

6、務(wù)部分得執(zhí)行。即使因為故障而使事務(wù)不能完成,在rollback時也要消除對數(shù)據(jù)庫得影響!     一致性(Consistency):事務(wù)得操作應(yīng)該使使數(shù)據(jù)庫從一個一致狀態(tài)轉(zhuǎn)變倒另一個一致得狀態(tài)!     隔離性(Isolation):如果多個事務(wù)并發(fā)執(zhí)行,應(yīng)象各個事務(wù)獨立執(zhí)行一樣!持久性(Durability):一個成功執(zhí)行得事務(wù)對數(shù)據(jù)庫得作用是持久得,即使數(shù)據(jù)庫應(yīng)故障出錯,也應(yīng)該能夠恢復!不加控制的并發(fā)存取會產(chǎn)生以下幾種錯誤1 丟失修改(lost updates) 當多個事務(wù)并發(fā)修改一個數(shù)據(jù)時,不加控制

7、會得出錯誤的結(jié)果,一個修改會覆蓋掉另一個修改。 2 讀的不可重復性 當多個事務(wù)按某種時間順序存取若干數(shù)據(jù)時,如果對并發(fā)存取不加控制,也會產(chǎn)生錯誤。 3 臟讀(DIRDY DATA),讀的不一致性 4 光標帶來的當前值的混亂 事務(wù)在執(zhí)行過程中它在某個表上的當前查找位置是由光標表示的。光標指向當前正處理的記錄。當處理完該條記錄后,則指向下一條記錄。在多個事務(wù)并發(fā)執(zhí)行時,某一事務(wù)的修改可能產(chǎn)生負作用,使與這些光標有關(guān)的事務(wù)出錯。 5 未釋放修改造成連鎖退出 一個事務(wù)在進行修改操作的過程中可能會發(fā)生故障,這時需要將已做的修改回退(R

8、ollback)。如果在已進行過或已發(fā)現(xiàn)錯誤尚未復原之前允許其它事務(wù)讀已做過修改(臟讀),則會導致連鎖退出。 6 一事務(wù)在對一表更新時,另外的事務(wù)卻修改或刪除此表的 定義。 數(shù)據(jù)庫會為每個事務(wù)自動地設(shè)置適當級別的鎖定。對于前面講述的問題:臟讀、未釋放修改造成的連鎖退出、一事務(wù)在對一表更新時另外的事務(wù)卻修改或刪除此表的定義,數(shù)據(jù)庫都會自動解決。而另外的三個問題則需要在編程過程中人為地定義事務(wù)或加鎖來解決。 事務(wù)處理的機制簡單地說就是留下更新日志。數(shù)據(jù)庫會根據(jù)這些日志信息,在必要時將舊數(shù)據(jù)取回,或者在發(fā)生錯誤時將數(shù)據(jù)恢復到原先的狀態(tài)。事務(wù)處理日志文件:UND

9、O log日志UNDO日志又被稱為回滾段(Rollback Segment),在進行數(shù)據(jù)的捕入、更新、刪除的場合,保存變更前的數(shù)據(jù),在表的內(nèi)容保存了指向UNDO日志的指針,ROLLBACK時根據(jù)這個指針米獲得舊數(shù)據(jù),并覆蓋新數(shù)據(jù)。ROLLBACK后,或者COMMIT后UNDO日志將被刪除。另外,UNDO日志也使用于保持數(shù)據(jù)讀取的整合性。例如,在用戶A對數(shù)據(jù)進行了更新,但還沒有提交時,用戶B要參照數(shù)據(jù)怎么辦呢?此時讓用戶B看到更新后的數(shù)據(jù)顯然是不行的,其實是通過保存的指針讓UNDO日志中的數(shù)據(jù)呈現(xiàn)給用戶B的。REDO log日志REDO日志根據(jù)數(shù)據(jù)庫的不同,有時被稱為事務(wù)處理日志或日志.事務(wù)處理

10、確定后,由于錯誤等原因使數(shù)據(jù)的更新沒有正確反映到數(shù)據(jù)庫中的時候,REDO日志提供了數(shù)據(jù)恢復用的孚段.僅僅看上述的說明可能還不能理解。那到底事務(wù)處理確定后,數(shù)據(jù)的更新沒有反映到數(shù)據(jù)庫中這種狀態(tài)是在什么時候發(fā)生的呢?這個必須首先說明。我們通常提到"更新(或變更)"就一句話帶過,其實在數(shù)據(jù)庫內(nèi)部是需要經(jīng)過較復雜的處理的過程的,一般在數(shù)據(jù)庫中進行更新處理時,并非立即更新數(shù)據(jù)文件,而是首先在被稱緩沖(buffer cash)的內(nèi)存空間中進行數(shù)據(jù)更新,并將這些保存到REDO日志文件中。到現(xiàn)在為止太家會以為所有的處理都是實時的,其實在數(shù)據(jù)庫中向數(shù)據(jù)文件寫入時是有延遲(或稱為滯后)的。向數(shù)

11、據(jù)文件的寫入動作是在觸發(fā)稱為檢查點( check point) 時非同步進行的。檢查點撥一定的周期觸發(fā)。如果頻繁進行這樣復雜的處理的話,尤其是對硬盤進行寫入處理時將會出現(xiàn)很高的負荷。因此現(xiàn)在的處理方式是,數(shù)據(jù)庫將對硬盤的寫入操作稍微保留片刻, 當檢查點(check point)到來時再集中處理,這樣就會顯著減少訪問硬盤的次數(shù),性能得到改善。問題出現(xiàn)在REDO日志的更新與數(shù)據(jù)文件的更新之間的延遲上。大家想象一下, 如果在這個延遲的當口發(fā)生了停電,硬件錯誤時會出現(xiàn)什么悄況呢?很顯然,內(nèi)存中的信息將會消失,只剩下在REDO日志中保存的信息了。REDO日志正是用于復原的.數(shù)據(jù)庫在錯誤排除后的第一次起動

12、時進行稱為Roll forward的處理,Roll forward處理具體做法是,從REDO日志中抽出從最后的檢查點到錯誤發(fā)生時間點間的事務(wù)處理,然后重新執(zhí)行一次(REDO)。這樣,數(shù)據(jù)庫就恢復到錯誤發(fā)生前的狀態(tài)了。Redo log undo log區(qū)別redo->記錄所有操作,用于恢復undo->記錄所有的前印象,用于回滾redo->已遞交的事務(wù),實例恢復時要寫到數(shù)據(jù)文件去的undo->未遞交的事務(wù).redo的原因是:每次commit時,將數(shù)據(jù)的修改立即寫到redo中,但是并不一定同時將該數(shù)據(jù)的修改寫到數(shù)據(jù)文件中。undo的原因是:口述。undo 也是也是datafi

13、le, 可能dirty buffer 沒有寫回到磁盤里面去。只有先redo apply 成功了,才能保證undo datafile 里面的東西都是正確的,然后才能rollback做undo的目的是使系統(tǒng)恢復到系統(tǒng)崩潰前(關(guān)機前)的狀態(tài),再進行redo是保證系統(tǒng)的一致性.不做undo,系統(tǒng)就不會知道之前的狀態(tài),redo就無從談起undo log原理使用undo log時,要求:1. 記錄修改日志時(redo log),(T,x,v)中v為x修改前的值,這樣才能借助這條日志來回滾;2. 事務(wù)提交后,必須在事務(wù)的所有修改(包括記錄的修改日志)都持久化后才能寫COMMIT T日志;這樣才能保證,宕機恢

14、復時,已經(jīng)COMMIT的事務(wù)的所有修改都已經(jīng)持久化,不需要回滾。 使用undo log時事務(wù)執(zhí)行順序1. 記錄START T 2. 記錄需要修改的記錄的舊值(要求持久化)3. 根據(jù)事務(wù)的需要更新數(shù)據(jù)庫(要求持久化)4. 記錄COMMIT T 使用undo log進行宕機回滾1. 掃描日志,找出所有已經(jīng)START,還沒有COMMIT的事務(wù)。2. 針對所有未COMMIT的日志,根據(jù)redo log來進行回滾。 如果數(shù)據(jù)庫訪問很多,日志量也會很大,宕機恢復時,回滾的工作量也就很大,為了加快回滾,可以通過checkpoint機制來加速回滾,在日志中記錄checkpoint_start (T1,T2Tn

15、) (Tx代表做checkpoint時,正在進行還未COMMIT的事務(wù))等待所有正在進行的事務(wù)(T1Tn)COMMIT在日志中記錄checkpoint_end借助checkpoint來進行回滾從后往前,掃描undo log1,如果先遇到checkpoint_start, 則將checkpoint_start之后的所有未提交的事務(wù)進行回滾;2. 如果先遇到checkpoint_end, 則將前一個checkpoint_start之后所有未提交的事務(wù)進行回滾;(在checkpoint的過程中,可能有很多新的事務(wù)START或者COMMIT)。 使用undo log,在寫COMMIT日志時,要求red

16、o log以及事務(wù)的所有修改都必須已經(jīng)持久化,這種做法通常很影響性能。redo log原理redo log是指在回放日志的時候把已經(jīng)COMMIT的事務(wù)重做一遍,對于沒有commit的事務(wù)按照abort處理,不進行任何操作。使用redo log時,要求:1. 記錄redo log時,(T,x,v)中的v必須是x修改后的值,否則不能通過redo log來恢復已經(jīng)COMMIT的事務(wù)。2. 寫COMMIT T日志之前,事務(wù)的修改不能進行持久化,否則恢復時,對于未COMMIT的操作,可能有數(shù)據(jù)已經(jīng)修改,但重放redo log不會對該事務(wù)做任何處理,從而不能保證事務(wù)的原子性。 使用redo log時事務(wù)執(zhí)

17、行順序1. 記錄START T2. 記錄事務(wù)需要修改記錄的新值(要求持久化)3. 記錄COMMIT T(要求持久化)4. 將事務(wù)相關(guān)的修改寫入數(shù)據(jù)庫 使用redo log重做事務(wù)1. 掃描日志,找到所有已經(jīng)COMMIT的事務(wù);2. 對于已經(jīng)COMMIT的事務(wù),根據(jù)redo log重做事務(wù); 在日志中使用checkpoint1. 在日志中記錄checkpoint_start (T1,T2.Tn) (Tx代表做checkpoint時,正在進行還未COMMIT的日志)2. 將所有已提交的事務(wù)的更改進行持久化;3. 在日志中記錄checkpoint_end 根據(jù)checkpoint來加速恢復從后往前,

18、掃描redo log1,如果先遇到checkpoint_start, 則把T1Tn以及checkpoint_start之后的所有已經(jīng)COMMIT的事務(wù)進行重做;2. 如果先遇到checkpoint_end, 則T1Tn以及前一個checkpoint_start之后所有已經(jīng)COMMIT的事務(wù)進行重做; 與undo log類似,在使用時對持久化以及事務(wù)操作順序的要求都比較高,可以將兩者結(jié)合起來使用,在恢復時,對于已經(jīng)COMMIT的事務(wù)使用redo log進行重做,對于沒有COMMIT的事務(wù),使用undo log進行回滾。redo/undo log結(jié)合起來使用時,要求同時記錄操作修改前和修改后的值,

19、如(T,x,v,w),v為x修改前的值,w為x修改后的值,具體操作順序為:1. 記錄START T2. 記錄修改日志(T,x,v,w)(要求持久化,其中v用于undo,w用于redo)3. 更新數(shù)據(jù)庫4. 記錄 COMMIT T 4和3的操作順序沒有嚴格要求,并且都不要求持久化;因為如果宕機時4已經(jīng)持久化,則恢復時可通過redo log來重做;如果宕機時4未持久化,則恢復時可通過undo log來回滾;在處理checkpoint時,可采用與redo log相同的處理方式。什么是binlogbinlog日志用于記錄所有更新且提交了數(shù)據(jù)或者已經(jīng)潛在更新提交了數(shù)據(jù)(例如,沒有匹配任何行的一個DELE

20、TE)的所有語句。語句以“事件”的形式保存,它描述數(shù)據(jù)更改。binlog作用1.恢復使能夠最大可能地更新數(shù)據(jù)庫,因為二進制日志包含備份后進行的所有更新。2.在主復制服務(wù)器上記錄所有將發(fā)送給從服務(wù)器的語句。 binlog未打卡狀態(tài)下的提交流程測試前置條件:set autocommit=0;create table tt(col1 int, col2 varchar(100); 測試語句:insert into tt values(1, 'abcdef');commit;     無論對于dml語句【insert,update,delete等

21、】還是dcl語句【commit,rollback】,mysql提供了公共接口mysql_execute_command,我們先分析mysql_execute_command接口的基本流程:<span style="font-size: 14px;">mysql_execute_command   switch (command)          case SQLCOM_INSERT:  

22、60;             mysql_insert();                break;         case SQLCOM_UPDATE:    

23、            mysql_update();                break;         case SQLCOM_DELETE:     

24、60;          mysql_delete();                break;       .           if thd->

25、is_error()  /語句執(zhí)行錯誤     trans_rollback_stmt(thd);  else    trans_commit_stmt(thd); </span>可以看到執(zhí)行任何語句最后,都會執(zhí)行trans_rollback_stmt,或trans_commit_stmt,這兩個調(diào)用分別是語句級提交和語句級回滾。語句級提交,對于非自動模式提交情況下,主要作兩件事情,一是釋放autoinc鎖(什么是他-口述),這個鎖主要用來處理多個事務(wù)互斥地獲取自

26、增列值,因此,無論最后該語句提交或是回滾,該資源都是需要而且可以立馬放掉的。二是標識語句在事務(wù)中位置,方便語句級回滾。執(zhí)行commit后,可以進入commit流程,現(xiàn)在來看看具體事務(wù)提交的流程是怎樣的。<span style="font-size: 14px;">mysql_execute_command    trans_commitha_commit_trans(thd, FALSE);    TC_LOG_DUMMY:ha_commit_low   

27、;     ha_commit_low()                innobase_commit                        

28、0;   /獲取innodb層對應(yīng)的事務(wù)結(jié)構(gòu)                trx = check_trx_exists(thd);                 if(單個語句,且非自動提交)   

29、0;                                 /釋放自增列占用的autoinc鎖資源             

30、60;       lock_unlock_table_autoinc(trx);                     /標識sql語句在事務(wù)中的位置,方便語句級回滾            

31、60;        trx_mark_sql_stat_end(trx);                                else 事務(wù)提交  

32、0;                                  innobase_commit_low()            &

33、#160;                                   trx_commit_for_mysql();            

34、                 <span style="color: #ff0000;">trx_commit</span>(trx);                     &#

35、160;  /確定事務(wù)對應(yīng)的redo日志是否落盤【根據(jù)flush_log_at_trx_commit參數(shù),確定redo日志落盤方式】                     trx_commit_complete_for_mysql(trx);trx_flush_log_if_needed_low(trx->commit_lsn);log_write_up_to

36、(lsn);                             </span><br><br>trx_commit    trx_commit_low         

37、           trx_write_serialisation_history                            trx_undo_update_cleanup /供purge線程處理,清理回滾頁      

38、60;                 trx_commit_in_memory                            lock_trx_release_locks /釋放鎖資源

39、60;               trx_flush_log_if_needed(lsn) /刷日志                trx_roll_savepoints_free /釋放savepoints             &#

40、160;            mysql通過WAL方式,來保證數(shù)據(jù)庫事務(wù)的一致性和持久性,即ACID特性中的C(consistent)和D(durability)。WAL(Write-Ahead Logging)是一種實現(xiàn)事務(wù)日志的標準方法,具體而言就是修改記錄前,一定要先寫日志;事務(wù)提交過程中,一定要保證日志先落盤,才能算事務(wù)提交完成。通過WAL方式,在保證事務(wù)特性的情況下,可以提交數(shù)據(jù)庫的性能。從上述流程可以看出,提交過程中,主要做了4件事情,首先是清理undo段信息,對于innodb存儲

41、引擎的更新操作來說,undo段需要purge,這里的purge主要職能是,真正刪除物理記錄。在執(zhí)行delete或update操作時,實際舊記錄沒有真正刪除,只是在記錄上打了一個標記,而是在事務(wù)提交后,purge線程真正刪除,釋放物理頁空間。因此,提交過程中會將undo信息加入purge列表,供purge線程處理。然后是釋放鎖資源,mysql通過鎖互斥機制保證不同事務(wù)不同時操作一條記錄,事務(wù)執(zhí)行后才會真正釋放所有鎖資源,并喚醒等待其鎖資源的其他事務(wù);再就是刷redo日志,前面我提到了,mysql實現(xiàn)事務(wù)一致性和持久性的機制。通過redo日志落盤操作,保證了即使修改的數(shù)據(jù)頁沒有即使更新到磁盤,只要

42、日志是完成了,就能保證數(shù)據(jù)庫的完整性和一致性;最后就是清理保存點列表,每個語句實際都會有一個savepoint(保存點),保存點作用是為了可以回滾到事務(wù)的任何一個語句執(zhí)行前的狀態(tài),由于事務(wù)都已經(jīng)提交了,所以保存點列表可以被清理了。     關(guān)于里面提到的mysql的鎖機制,purge原理,redo日志,undo段等內(nèi)容,以后再說。<span style="font-size: 14px;">struct trx_t         t

43、rx_rseg_t* rseg;       /*!< rollback segment assigned to the                    transaction, or NULL if not assigned        

44、60;trx_undo_t* insert_undo;    /*!< pointer to the insert undo log, or                    NULL if no inserts performed yet */    trx_undo_t* update_undo; 

45、60;  /*!< pointer to the update undo log, or                    NULL if no update performed yet */    const char* mysql_log_;       

46、             /*!< if MySQL binlog is used, this field                    contains a pointer to the latest file   

47、0;                name; this is NULL if binlog is not                    used */    ib_int64_t 

48、 mysql_log_offset;                    /*!< if MySQL binlog is used, this                    field

49、 contains the end offset of the                    binlog entry */  /* The rollback segment memory object */struct trx_rseg_t    /* Fields for update undo logs */

50、60;   UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_list;                    /* List of update undo logs */    UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_cached; 

51、;                   /* List of update undo log segments                    cached for fast reuse */ 

52、   /*-*/    /* Fields for insert undo logs */    UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_list;                    /* List of insert undo logs

53、 */    UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_cached;                    /* List of insert undo log segments           &

54、#160;        cached for fast reuse */</span>binlog打開狀態(tài)下的提交流程開啟binlog后事務(wù)提交流程會變成兩階段提交,這里的兩階段提交并不涉及分布式事務(wù),當然mysql把它稱之為內(nèi)部xa事務(wù)(Distributed Transactions),與之對應(yīng)的還有一個外部xa事務(wù)。內(nèi)部xa事務(wù)我理解主要是mysql內(nèi)部為了保證binlog與redo log之間數(shù)據(jù)的一致性而存在的,這也是由其架構(gòu)決定的(binlog在mysql層,而redo log 在存儲引擎

55、層);而外部xa事務(wù)則是指支持多實例分布式事務(wù),這個才算是真正的分布式事務(wù)。既然是xa事務(wù),必然涉及到兩階段提交,對于內(nèi)部xa而言,同樣存在著提交的兩個階段。下文會結(jié)合源碼詳細解讀內(nèi)部xa的兩階段提交過程,以及各種情況下,mysqld crash后,mysql如何恢復來保證事務(wù)的一致性。測試環(huán)境:OS:windowsDB:mysql 5.6.12engine:innodb 配置文件參數(shù):log-bin=D:chuckmysqllog5-6-12mysql-binbinlog_format=ROWset autocommit=0;sync_binlog=1;innodb_flush_l

56、og_at_trx_commit=1;innodb_support_xa=1; 測試前置條件:create table tt(col1 int, col2 varchar(100); 測試語句:insert into tt values(1, 'abcdef');commit;      打開binlog選項后,執(zhí)行事務(wù)提交命令時,就會進入兩階段提交模式。兩階段提交分為prepare階段和commit兩個階段。流程如下 :這里面涉及到兩個重要的參數(shù):innodb_flush_log_at_trx_commit和sync

57、_binlog,參數(shù)可以設(shè)置不同的值,具體可以查看mysql的幫助手冊。我這里設(shè)置的是雙一模式(innodb_flush_log_at_trx_commit=1,sync_binlog=1),不同的模式區(qū)別在于,寫文件調(diào)用write和落盤fsync調(diào)用的頻率不同,所導致的后果是mysqld 或 os crash后,不嚴格的設(shè)置可能會丟失事務(wù)的更新。雙一模式是最嚴格的模式,這種設(shè)置情況下,單機在任何情況下不會丟失事務(wù)更新。prepare階段:    1.設(shè)置undo state=TRX_UNDO_PREPARED; /trx_undo_set_state_at_prepare

58、調(diào)用    2.刷事務(wù)更新產(chǎn)生的redo日志;【步驟1產(chǎn)生的redo日志也會刷入】    commit階段:   1.將事務(wù)產(chǎn)生的binlog寫入文件,刷入磁盤;   2.設(shè)置undo頁的狀態(tài),置為TRX_UNDO_TO_FREE或TRX_UNDO_TO_PURGE;  / trx_undo_set_state_at_finish調(diào)用   3.記錄事務(wù)對應(yīng)的binlog偏移,寫入系統(tǒng)表空間; /trx_sys_update_mysql_binlo

59、g_offset調(diào)用        下面這部分是我抽象出來的源碼調(diào)用部分,大家可以通過單步調(diào)試方式,在關(guān)鍵函數(shù)中設(shè)置斷點,來詳細了解這個過程。= prepare階段=MYSQL_BIN_LOG:prepare    ha_prepare_low    engine:binlog_prepareinnobase_xa_preparemysql:trx_prepare_for_mysql        

60、;        1.trx_undo_set_state_at_prepare    /設(shè)置undo段的標記為TRX_UNDO_PREPARED                2.設(shè)置事務(wù)狀態(tài)為TRX_STATE_PREPARED         

61、       3.trx_flush_log_if_needed  /將產(chǎn)生的redolog刷入磁盤                      =commit階段=MYSQL_BIN_LOG:commit    ordered_commit   1.FLUSH_STAGE 

62、60;      flush_cache_to_file  /  刷binlog 2.SYNC_STAGE        sync_binlog_file    /Call fsync() to sync the disk. 3.COMMIT_STAGE        ha_commit_low   

63、0;                binlog_commit            innobase_commit                   trx_commit(trx)     

64、60;                               trx_write_serialisation_history(trx, mtr);  /更新binlog位點,設(shè)置undo狀態(tài)         

65、60;          trx_commit_in_memory(trx, lsn); /釋放鎖資源,清理保存點列表,清理回滾段                               

66、;             mysqld可能在任何情況下crash,os也有可能出現(xiàn)問題,另外若機器掉電,mysqld也會同樣掛掉。但是即使這樣,mysql仍然能保證數(shù)據(jù)庫的一致性。接下來,我會結(jié)合上述流程,分析二階段提交如何保證這點的。下面給出幾種常見的場景,1.prepare階段,redo log落盤前,mysqld crash2.prepare階段,redo log落盤后,binlog落盤前,mysqld crashmit階段,binlog落盤后,mysqld crash      對于第一種情況,由于redo沒有落盤,毫無疑問,事務(wù)的更新肯定沒有寫入磁盤,數(shù)據(jù)庫的一致性受影響;對于第二種情況,這時候redo log寫入完成,但binlog還未寫入,事務(wù)處于TRX_STATE_PREPARED狀態(tài),這是提交還是回滾呢?對于第三種情況,此時,redo log和binlog都已經(jīng)落盤,只是und

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論