




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、什么是事務(wù)事務(wù)就是一段sql 語(yǔ)句的批處理,但是這個(gè)批處理是一個(gè)atom(原子),不可分割,要么都執(zhí)行,要么回滾(rollback)都不執(zhí)行。(保證數(shù)據(jù)操作的安全性)為什么出現(xiàn)這種技術(shù)為什么要使用事務(wù)這個(gè)技術(shù)呢? 現(xiàn)在的很多軟件都是多用戶(hù),多程序,多線程的,對(duì)同一個(gè)表可能同時(shí)有很多人在用,為保持?jǐn)?shù)據(jù)的一致性,所以提出了事務(wù)的概念。這樣很抽象,舉個(gè)例子-口述。如何使用事務(wù)(1)只有InnoDB /BDB的之類(lèi)的transaction_safe table(commit-or-rollback,如果是安全的) 才能支持。默認(rèn)的engine
2、;MyISAM 是不支持事務(wù)的。建立InnoDB 表:Create table . type=InnoDB; Alter table table_name type=InnoDB;(如何查看已有表的類(lèi)型: show create table table_name)這樣我們就可以在InnoDB 表上進(jìn)行事務(wù)操作了!(2)啟動(dòng)事務(wù)的方法-2種:1、(推薦)begin ,rollback,commit .當(dāng)然有的人用begin /
3、begin work .推薦用START TRANSACTION 是SQL-99標(biāo)準(zhǔn)啟動(dòng)一個(gè)事務(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;解釋?zhuān)?#160;這樣start transaction 手動(dòng)開(kāi)啟事務(wù),commit 手動(dòng)關(guān)閉事務(wù)。2、默認(rèn)的時(shí)候autocommit=1 自動(dòng)提交是開(kāi)啟的,所以你可以理解為每條語(yǔ)句一輸入到mysql就commit 了。當(dāng)你 set autocommit=0 時(shí)候,你可以這樣:update from account set money=money-100 where name='a'update from
5、account set money=money+100 where name='b'commit;/ 默認(rèn)都不提交,只有手動(dòng)鍵入commit 時(shí)候才上述都提交。但注意當(dāng)你用 set autocommit=0 的時(shí)候,你以后所有的SQL都將做為事務(wù)處理,直到你用commit確認(rèn)或rollback結(jié)束,注意當(dāng)你結(jié)束這個(gè)事務(wù)的同時(shí)也開(kāi)啟了個(gè)新的事務(wù)事務(wù)是必須滿(mǎn)足4個(gè)條件(ACID) 原子性(Autmic):事務(wù)在執(zhí)行性,要做到“要么不做,要么全做!”,就是說(shuō)不允許事
6、務(wù)部分得執(zhí)行。即使因?yàn)楣收隙故聞?wù)不能完成,在rollback時(shí)也要消除對(duì)數(shù)據(jù)庫(kù)得影響! 一致性(Consistency):事務(wù)得操作應(yīng)該使使數(shù)據(jù)庫(kù)從一個(gè)一致?tīng)顟B(tài)轉(zhuǎn)變倒另一個(gè)一致得狀態(tài)! 隔離性(Isolation):如果多個(gè)事務(wù)并發(fā)執(zhí)行,應(yīng)象各個(gè)事務(wù)獨(dú)立執(zhí)行一樣!持久性(Durability):一個(gè)成功執(zhí)行得事務(wù)對(duì)數(shù)據(jù)庫(kù)得作用是持久得,即使數(shù)據(jù)庫(kù)應(yīng)故障出錯(cuò),也應(yīng)該能夠恢復(fù)!不加控制的并發(fā)存取會(huì)產(chǎn)生以下幾種錯(cuò)誤1 丟失修改(lost updates) 當(dāng)多個(gè)事務(wù)并發(fā)修改一個(gè)數(shù)據(jù)時(shí),不加控制
7、會(huì)得出錯(cuò)誤的結(jié)果,一個(gè)修改會(huì)覆蓋掉另一個(gè)修改。 2 讀的不可重復(fù)性 當(dāng)多個(gè)事務(wù)按某種時(shí)間順序存取若干數(shù)據(jù)時(shí),如果對(duì)并發(fā)存取不加控制,也會(huì)產(chǎn)生錯(cuò)誤。 3 臟讀(DIRDY DATA),讀的不一致性 4 光標(biāo)帶來(lái)的當(dāng)前值的混亂 事務(wù)在執(zhí)行過(guò)程中它在某個(gè)表上的當(dāng)前查找位置是由光標(biāo)表示的。光標(biāo)指向當(dāng)前正處理的記錄。當(dāng)處理完該條記錄后,則指向下一條記錄。在多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),某一事務(wù)的修改可能產(chǎn)生負(fù)作用,使與這些光標(biāo)有關(guān)的事務(wù)出錯(cuò)。 5 未釋放修改造成連鎖退出 一個(gè)事務(wù)在進(jìn)行修改操作的過(guò)程中可能會(huì)發(fā)生故障,這時(shí)需要將已做的修改回退(R
8、ollback)。如果在已進(jìn)行過(guò)或已發(fā)現(xiàn)錯(cuò)誤尚未復(fù)原之前允許其它事務(wù)讀已做過(guò)修改(臟讀),則會(huì)導(dǎo)致連鎖退出。 6 一事務(wù)在對(duì)一表更新時(shí),另外的事務(wù)卻修改或刪除此表的 定義。 數(shù)據(jù)庫(kù)會(huì)為每個(gè)事務(wù)自動(dòng)地設(shè)置適當(dāng)級(jí)別的鎖定。對(duì)于前面講述的問(wèn)題:臟讀、未釋放修改造成的連鎖退出、一事務(wù)在對(duì)一表更新時(shí)另外的事務(wù)卻修改或刪除此表的定義,數(shù)據(jù)庫(kù)都會(huì)自動(dòng)解決。而另外的三個(gè)問(wèn)題則需要在編程過(guò)程中人為地定義事務(wù)或加鎖來(lái)解決。 事務(wù)處理的機(jī)制簡(jiǎn)單地說(shuō)就是留下更新日志。數(shù)據(jù)庫(kù)會(huì)根據(jù)這些日志信息,在必要時(shí)將舊數(shù)據(jù)取回,或者在發(fā)生錯(cuò)誤時(shí)將數(shù)據(jù)恢復(fù)到原先的狀態(tài)。事務(wù)處理日志文件:UND
9、O log日志UNDO日志又被稱(chēng)為回滾段(Rollback Segment),在進(jìn)行數(shù)據(jù)的捕入、更新、刪除的場(chǎng)合,保存變更前的數(shù)據(jù),在表的內(nèi)容保存了指向UNDO日志的指針,ROLLBACK時(shí)根據(jù)這個(gè)指針米獲得舊數(shù)據(jù),并覆蓋新數(shù)據(jù)。ROLLBACK后,或者COMMIT后UNDO日志將被刪除。另外,UNDO日志也使用于保持?jǐn)?shù)據(jù)讀取的整合性。例如,在用戶(hù)A對(duì)數(shù)據(jù)進(jìn)行了更新,但還沒(méi)有提交時(shí),用戶(hù)B要參照數(shù)據(jù)怎么辦呢?此時(shí)讓用戶(hù)B看到更新后的數(shù)據(jù)顯然是不行的,其實(shí)是通過(guò)保存的指針讓UNDO日志中的數(shù)據(jù)呈現(xiàn)給用戶(hù)B的。REDO log日志REDO日志根據(jù)數(shù)據(jù)庫(kù)的不同,有時(shí)被稱(chēng)為事務(wù)處理日志或日志.事務(wù)處理
10、確定后,由于錯(cuò)誤等原因使數(shù)據(jù)的更新沒(méi)有正確反映到數(shù)據(jù)庫(kù)中的時(shí)候,REDO日志提供了數(shù)據(jù)恢復(fù)用的孚段.僅僅看上述的說(shuō)明可能還不能理解。那到底事務(wù)處理確定后,數(shù)據(jù)的更新沒(méi)有反映到數(shù)據(jù)庫(kù)中這種狀態(tài)是在什么時(shí)候發(fā)生的呢?這個(gè)必須首先說(shuō)明。我們通常提到"更新(或變更)"就一句話帶過(guò),其實(shí)在數(shù)據(jù)庫(kù)內(nèi)部是需要經(jīng)過(guò)較復(fù)雜的處理的過(guò)程的,一般在數(shù)據(jù)庫(kù)中進(jìn)行更新處理時(shí),并非立即更新數(shù)據(jù)文件,而是首先在被稱(chēng)緩沖(buffer cash)的內(nèi)存空間中進(jìn)行數(shù)據(jù)更新,并將這些保存到REDO日志文件中。到現(xiàn)在為止太家會(huì)以為所有的處理都是實(shí)時(shí)的,其實(shí)在數(shù)據(jù)庫(kù)中向數(shù)據(jù)文件寫(xiě)入時(shí)是有延遲(或稱(chēng)為滯后)的。向數(shù)
11、據(jù)文件的寫(xiě)入動(dòng)作是在觸發(fā)稱(chēng)為檢查點(diǎn)( check point) 時(shí)非同步進(jìn)行的。檢查點(diǎn)撥一定的周期觸發(fā)。如果頻繁進(jìn)行這樣復(fù)雜的處理的話,尤其是對(duì)硬盤(pán)進(jìn)行寫(xiě)入處理時(shí)將會(huì)出現(xiàn)很高的負(fù)荷。因此現(xiàn)在的處理方式是,數(shù)據(jù)庫(kù)將對(duì)硬盤(pán)的寫(xiě)入操作稍微保留片刻, 當(dāng)檢查點(diǎn)(check point)到來(lái)時(shí)再集中處理,這樣就會(huì)顯著減少訪問(wèn)硬盤(pán)的次數(shù),性能得到改善。問(wèn)題出現(xiàn)在REDO日志的更新與數(shù)據(jù)文件的更新之間的延遲上。大家想象一下, 如果在這個(gè)延遲的當(dāng)口發(fā)生了停電,硬件錯(cuò)誤時(shí)會(huì)出現(xiàn)什么悄況呢?很顯然,內(nèi)存中的信息將會(huì)消失,只剩下在REDO日志中保存的信息了。REDO日志正是用于復(fù)原的.數(shù)據(jù)庫(kù)在錯(cuò)誤排除后的第一次起動(dòng)
12、時(shí)進(jìn)行稱(chēng)為Roll forward的處理,Roll forward處理具體做法是,從REDO日志中抽出從最后的檢查點(diǎn)到錯(cuò)誤發(fā)生時(shí)間點(diǎn)間的事務(wù)處理,然后重新執(zhí)行一次(REDO)。這樣,數(shù)據(jù)庫(kù)就恢復(fù)到錯(cuò)誤發(fā)生前的狀態(tài)了。Redo log undo log區(qū)別redo->記錄所有操作,用于恢復(fù)undo->記錄所有的前印象,用于回滾redo->已遞交的事務(wù),實(shí)例恢復(fù)時(shí)要寫(xiě)到數(shù)據(jù)文件去的undo->未遞交的事務(wù).redo的原因是:每次commit時(shí),將數(shù)據(jù)的修改立即寫(xiě)到redo中,但是并不一定同時(shí)將該數(shù)據(jù)的修改寫(xiě)到數(shù)據(jù)文件中。undo的原因是:口述。undo 也是也是datafi
13、le, 可能dirty buffer 沒(méi)有寫(xiě)回到磁盤(pán)里面去。只有先redo apply 成功了,才能保證undo datafile 里面的東西都是正確的,然后才能rollback做undo的目的是使系統(tǒng)恢復(fù)到系統(tǒng)崩潰前(關(guān)機(jī)前)的狀態(tài),再進(jìn)行redo是保證系統(tǒng)的一致性.不做undo,系統(tǒng)就不會(huì)知道之前的狀態(tài),redo就無(wú)從談起undo log原理使用undo log時(shí),要求:1. 記錄修改日志時(shí)(redo log),(T,x,v)中v為x修改前的值,這樣才能借助這條日志來(lái)回滾;2. 事務(wù)提交后,必須在事務(wù)的所有修改(包括記錄的修改日志)都持久化后才能寫(xiě)COMMIT T日志;這樣才能保證,宕機(jī)恢
14、復(fù)時(shí),已經(jīng)COMMIT的事務(wù)的所有修改都已經(jīng)持久化,不需要回滾。 使用undo log時(shí)事務(wù)執(zhí)行順序1. 記錄START T 2. 記錄需要修改的記錄的舊值(要求持久化)3. 根據(jù)事務(wù)的需要更新數(shù)據(jù)庫(kù)(要求持久化)4. 記錄COMMIT T 使用undo log進(jìn)行宕機(jī)回滾1. 掃描日志,找出所有已經(jīng)START,還沒(méi)有COMMIT的事務(wù)。2. 針對(duì)所有未COMMIT的日志,根據(jù)redo log來(lái)進(jìn)行回滾。 如果數(shù)據(jù)庫(kù)訪問(wèn)很多,日志量也會(huì)很大,宕機(jī)恢復(fù)時(shí),回滾的工作量也就很大,為了加快回滾,可以通過(guò)checkpoint機(jī)制來(lái)加速回滾,在日志中記錄checkpoint_start (T1,T2Tn
15、) (Tx代表做checkpoint時(shí),正在進(jìn)行還未COMMIT的事務(wù))等待所有正在進(jìn)行的事務(wù)(T1Tn)COMMIT在日志中記錄checkpoint_end借助checkpoint來(lái)進(jìn)行回滾從后往前,掃描undo log1,如果先遇到checkpoint_start, 則將checkpoint_start之后的所有未提交的事務(wù)進(jìn)行回滾;2. 如果先遇到checkpoint_end, 則將前一個(gè)checkpoint_start之后所有未提交的事務(wù)進(jìn)行回滾;(在checkpoint的過(guò)程中,可能有很多新的事務(wù)START或者COMMIT)。 使用undo log,在寫(xiě)COMMIT日志時(shí),要求red
16、o log以及事務(wù)的所有修改都必須已經(jīng)持久化,這種做法通常很影響性能。redo log原理redo log是指在回放日志的時(shí)候把已經(jīng)COMMIT的事務(wù)重做一遍,對(duì)于沒(méi)有commit的事務(wù)按照abort處理,不進(jìn)行任何操作。使用redo log時(shí),要求:1. 記錄redo log時(shí),(T,x,v)中的v必須是x修改后的值,否則不能通過(guò)redo log來(lái)恢復(fù)已經(jīng)COMMIT的事務(wù)。2. 寫(xiě)COMMIT T日志之前,事務(wù)的修改不能進(jìn)行持久化,否則恢復(fù)時(shí),對(duì)于未COMMIT的操作,可能有數(shù)據(jù)已經(jīng)修改,但重放redo log不會(huì)對(duì)該事務(wù)做任何處理,從而不能保證事務(wù)的原子性。 使用redo log時(shí)事務(wù)執(zhí)
17、行順序1. 記錄START T2. 記錄事務(wù)需要修改記錄的新值(要求持久化)3. 記錄COMMIT T(要求持久化)4. 將事務(wù)相關(guān)的修改寫(xiě)入數(shù)據(jù)庫(kù) 使用redo log重做事務(wù)1. 掃描日志,找到所有已經(jīng)COMMIT的事務(wù);2. 對(duì)于已經(jīng)COMMIT的事務(wù),根據(jù)redo log重做事務(wù); 在日志中使用checkpoint1. 在日志中記錄checkpoint_start (T1,T2.Tn) (Tx代表做checkpoint時(shí),正在進(jìn)行還未COMMIT的日志)2. 將所有已提交的事務(wù)的更改進(jìn)行持久化;3. 在日志中記錄checkpoint_end 根據(jù)checkpoint來(lái)加速恢復(fù)從后往前,
18、掃描redo log1,如果先遇到checkpoint_start, 則把T1Tn以及checkpoint_start之后的所有已經(jīng)COMMIT的事務(wù)進(jìn)行重做;2. 如果先遇到checkpoint_end, 則T1Tn以及前一個(gè)checkpoint_start之后所有已經(jīng)COMMIT的事務(wù)進(jìn)行重做; 與undo log類(lèi)似,在使用時(shí)對(duì)持久化以及事務(wù)操作順序的要求都比較高,可以將兩者結(jié)合起來(lái)使用,在恢復(fù)時(shí),對(duì)于已經(jīng)COMMIT的事務(wù)使用redo log進(jìn)行重做,對(duì)于沒(méi)有COMMIT的事務(wù),使用undo log進(jìn)行回滾。redo/undo log結(jié)合起來(lái)使用時(shí),要求同時(shí)記錄操作修改前和修改后的值,
19、如(T,x,v,w),v為x修改前的值,w為x修改后的值,具體操作順序?yàn)椋?. 記錄START T2. 記錄修改日志(T,x,v,w)(要求持久化,其中v用于undo,w用于redo)3. 更新數(shù)據(jù)庫(kù)4. 記錄 COMMIT T 4和3的操作順序沒(méi)有嚴(yán)格要求,并且都不要求持久化;因?yàn)槿绻礄C(jī)時(shí)4已經(jīng)持久化,則恢復(fù)時(shí)可通過(guò)redo log來(lái)重做;如果宕機(jī)時(shí)4未持久化,則恢復(fù)時(shí)可通過(guò)undo log來(lái)回滾;在處理checkpoint時(shí),可采用與redo log相同的處理方式。什么是binlogbinlog日志用于記錄所有更新且提交了數(shù)據(jù)或者已經(jīng)潛在更新提交了數(shù)據(jù)(例如,沒(méi)有匹配任何行的一個(gè)DELE
20、TE)的所有語(yǔ)句。語(yǔ)句以“事件”的形式保存,它描述數(shù)據(jù)更改。binlog作用1.恢復(fù)使能夠最大可能地更新數(shù)據(jù)庫(kù),因?yàn)槎M(jìn)制日志包含備份后進(jìn)行的所有更新。2.在主復(fù)制服務(wù)器上記錄所有將發(fā)送給從服務(wù)器的語(yǔ)句。 binlog未打卡狀態(tài)下的提交流程測(cè)試前置條件:set autocommit=0;create table tt(col1 int, col2 varchar(100); 測(cè)試語(yǔ)句:insert into tt values(1, 'abcdef');commit; 無(wú)論對(duì)于dml語(yǔ)句【insert,update,delete等
21、】還是dcl語(yǔ)句【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() /語(yǔ)句執(zhí)行錯(cuò)誤 trans_rollback_stmt(thd); else trans_commit_stmt(thd); </span>可以看到執(zhí)行任何語(yǔ)句最后,都會(huì)執(zhí)行trans_rollback_stmt,或trans_commit_stmt,這兩個(gè)調(diào)用分別是語(yǔ)句級(jí)提交和語(yǔ)句級(jí)回滾。語(yǔ)句級(jí)提交,對(duì)于非自動(dòng)模式提交情況下,主要作兩件事情,一是釋放autoinc鎖(什么是他-口述),這個(gè)鎖主要用來(lái)處理多個(gè)事務(wù)互斥地獲取自
26、增列值,因此,無(wú)論最后該語(yǔ)句提交或是回滾,該資源都是需要而且可以立馬放掉的。二是標(biāo)識(shí)語(yǔ)句在事務(wù)中位置,方便語(yǔ)句級(jí)回滾。執(zhí)行commit后,可以進(jìn)入commit流程,現(xiàn)在來(lái)看看具體事務(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層對(duì)應(yīng)的事務(wù)結(jié)構(gòu) trx = check_trx_exists(thd); if(單個(gè)語(yǔ)句,且非自動(dòng)提交)
29、0; /釋放自增列占用的autoinc鎖資源
30、60; lock_unlock_table_autoinc(trx); /標(biāo)識(shí)sql語(yǔ)句在事務(wù)中的位置,方便語(yǔ)句級(jí)回滾
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ù)對(duì)應(yīng)的redo日志是否落盤(pán)【根據(jù)flush_log_at_trx_commit參數(shù),確定redo日志落盤(pán)方式】 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線程處理,清理回滾頁(yè)
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通過(guò)WAL方式,來(lái)保證數(shù)據(jù)庫(kù)事務(wù)的一致性和持久性,即ACID特性中的C(consistent)和D(durability)。WAL(Write-Ahead Logging)是一種實(shí)現(xiàn)事務(wù)日志的標(biāo)準(zhǔn)方法,具體而言就是修改記錄前,一定要先寫(xiě)日志;事務(wù)提交過(guò)程中,一定要保證日志先落盤(pán),才能算事務(wù)提交完成。通過(guò)WAL方式,在保證事務(wù)特性的情況下,可以提交數(shù)據(jù)庫(kù)的性能。從上述流程可以看出,提交過(guò)程中,主要做了4件事情,首先是清理undo段信息,對(duì)于innodb存儲(chǔ)
41、引擎的更新操作來(lái)說(shuō),undo段需要purge,這里的purge主要職能是,真正刪除物理記錄。在執(zhí)行delete或update操作時(shí),實(shí)際舊記錄沒(méi)有真正刪除,只是在記錄上打了一個(gè)標(biāo)記,而是在事務(wù)提交后,purge線程真正刪除,釋放物理頁(yè)空間。因此,提交過(guò)程中會(huì)將undo信息加入purge列表,供purge線程處理。然后是釋放鎖資源,mysql通過(guò)鎖互斥機(jī)制保證不同事務(wù)不同時(shí)操作一條記錄,事務(wù)執(zhí)行后才會(huì)真正釋放所有鎖資源,并喚醒等待其鎖資源的其他事務(wù);再就是刷redo日志,前面我提到了,mysql實(shí)現(xiàn)事務(wù)一致性和持久性的機(jī)制。通過(guò)redo日志落盤(pán)操作,保證了即使修改的數(shù)據(jù)頁(yè)沒(méi)有即使更新到磁盤(pán),只要
42、日志是完成了,就能保證數(shù)據(jù)庫(kù)的完整性和一致性;最后就是清理保存點(diǎn)列表,每個(gè)語(yǔ)句實(shí)際都會(huì)有一個(gè)savepoint(保存點(diǎn)),保存點(diǎn)作用是為了可以回滾到事務(wù)的任何一個(gè)語(yǔ)句執(zhí)行前的狀態(tài),由于事務(wù)都已經(jīng)提交了,所以保存點(diǎn)列表可以被清理了。 關(guān)于里面提到的mysql的鎖機(jī)制,purge原理,redo日志,undo段等內(nèi)容,以后再說(shuō)。<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打開(kāi)狀態(tài)下的提交流程開(kāi)啟binlog后事務(wù)提交流程會(huì)變成兩階段提交,這里的兩階段提交并不涉及分布式事務(wù),當(dāng)然mysql把它稱(chēng)之為內(nèi)部xa事務(wù)(Distributed Transactions),與之對(duì)應(yīng)的還有一個(gè)外部xa事務(wù)。內(nèi)部xa事務(wù)我理解主要是mysql內(nèi)部為了保證binlog與redo log之間數(shù)據(jù)的一致性而存在的,這也是由其架構(gòu)決定的(binlog在mysql層,而redo log 在存儲(chǔ)引擎
55、層);而外部xa事務(wù)則是指支持多實(shí)例分布式事務(wù),這個(gè)才算是真正的分布式事務(wù)。既然是xa事務(wù),必然涉及到兩階段提交,對(duì)于內(nèi)部xa而言,同樣存在著提交的兩個(gè)階段。下文會(huì)結(jié)合源碼詳細(xì)解讀內(nèi)部xa的兩階段提交過(guò)程,以及各種情況下,mysqld crash后,mysql如何恢復(fù)來(lái)保證事務(wù)的一致性。測(cè)試環(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; 測(cè)試前置條件:create table tt(col1 int, col2 varchar(100); 測(cè)試語(yǔ)句:insert into tt values(1, 'abcdef');commit; 打開(kāi)binlog選項(xiàng)后,執(zhí)行事務(wù)提交命令時(shí),就會(huì)進(jìn)入兩階段提交模式。兩階段提交分為prepare階段和commit兩個(gè)階段。流程如下 :這里面涉及到兩個(gè)重要的參數(shù):innodb_flush_log_at_trx_commit和sync
57、_binlog,參數(shù)可以設(shè)置不同的值,具體可以查看mysql的幫助手冊(cè)。我這里設(shè)置的是雙一模式(innodb_flush_log_at_trx_commit=1,sync_binlog=1),不同的模式區(qū)別在于,寫(xiě)文件調(diào)用write和落盤(pán)fsync調(diào)用的頻率不同,所導(dǎo)致的后果是mysqld 或 os crash后,不嚴(yán)格的設(shè)置可能會(huì)丟失事務(wù)的更新。雙一模式是最嚴(yán)格的模式,這種設(shè)置情況下,單機(jī)在任何情況下不會(huì)丟失事務(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日志也會(huì)刷入】 commit階段: 1.將事務(wù)產(chǎn)生的binlog寫(xiě)入文件,刷入磁盤(pán); 2.設(shè)置undo頁(yè)的狀態(tài),置為T(mén)RX_UNDO_TO_FREE或TRX_UNDO_TO_PURGE; / trx_undo_set_state_at_finish調(diào)用 3.記錄事務(wù)對(duì)應(yīng)的binlog偏移,寫(xiě)入系統(tǒng)表空間; /trx_sys_update_mysql_binlo
59、g_offset調(diào)用 下面這部分是我抽象出來(lái)的源碼調(diào)用部分,大家可以通過(guò)單步調(diào)試方式,在關(guān)鍵函數(shù)中設(shè)置斷點(diǎn),來(lái)詳細(xì)了解這個(gè)過(guò)程。= 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段的標(biāo)記為T(mén)RX_UNDO_PREPARED 2.設(shè)置事務(wù)狀態(tài)為T(mén)RX_STATE_PREPARED
61、 3.trx_flush_log_if_needed /將產(chǎn)生的redolog刷入磁盤(pán) =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位點(diǎn),設(shè)置undo狀態(tài)
65、60; trx_commit_in_memory(trx, lsn); /釋放鎖資源,清理保存點(diǎn)列表,清理回滾段
66、; mysqld可能在任何情況下crash,os也有可能出現(xiàn)問(wèn)題,另外若機(jī)器掉電,mysqld也會(huì)同樣掛掉。但是即使這樣,mysql仍然能保證數(shù)據(jù)庫(kù)的一致性。接下來(lái),我會(huì)結(jié)合上述流程,分析二階段提交如何保證這點(diǎn)的。下面給出幾種常見(jiàn)的場(chǎng)景,1.prepare階段,redo log落盤(pán)前,mysqld crash2.prepare階段,redo log落盤(pán)后,binlog落盤(pán)前,mysqld crashmit階段,binlog落盤(pán)后,mysqld crash 對(duì)于第一種情況,由于redo沒(méi)有落盤(pán),毫無(wú)疑問(wèn),事務(wù)的更新肯定沒(méi)有寫(xiě)入磁盤(pán),數(shù)據(jù)庫(kù)的一致性受影響;對(duì)于第二種情況,這時(shí)候redo log寫(xiě)入完成,但binlog還未寫(xiě)入,事務(wù)處于TRX_STATE_PREPARED狀態(tài),這是提交還是回滾呢?對(duì)于第三種情況,此時(shí),redo log和binlog都已經(jīng)落盤(pán),只是und
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 榆林市榆陽(yáng)區(qū)2025年五年級(jí)數(shù)學(xué)第二學(xué)期期末考試模擬試題含答案
- 江蘇省啟東市長(zhǎng)江中學(xué)2025屆高考沖刺七歷史試題含解析
- 內(nèi)蒙古鄂爾多斯市鄂托克旗2024-2025學(xué)年初三期末熱身聯(lián)考英語(yǔ)試題含答案
- 玉柴職業(yè)技術(shù)學(xué)院《搜索引擎系統(tǒng)應(yīng)用實(shí)踐》2023-2024學(xué)年第二學(xué)期期末試卷
- 四川華新現(xiàn)代職業(yè)學(xué)院《大學(xué)英語(yǔ)III》2023-2024學(xué)年第二學(xué)期期末試卷
- 上海海事大學(xué)《科技檔案管理》2023-2024學(xué)年第一學(xué)期期末試卷
- 天津美術(shù)學(xué)院《診斷學(xué)(二)》2023-2024學(xué)年第二學(xué)期期末試卷
- 寧夏工業(yè)職業(yè)學(xué)院《生物醫(yī)藥與新材料化工科研創(chuàng)新訓(xùn)練》2023-2024學(xué)年第二學(xué)期期末試卷
- 山西省晉中學(xué)市榆社縣2024-2025學(xué)年初三中考考前輔導(dǎo)生物試題含解析
- 南通職業(yè)大學(xué)《臨床檢驗(yàn)設(shè)備與技術(shù)實(shí)驗(yàn)》2023-2024學(xué)年第二學(xué)期期末試卷
- 委托選礦加工合同協(xié)議
- 食堂應(yīng)急預(yù)案管理制度
- CISP-PTE培訓(xùn)課件教學(xué)課件
- 2025年新高考?xì)v史預(yù)測(cè)模擬試卷黑吉遼蒙卷(含答案解析)
- 2025年醫(yī)院文化節(jié)活動(dòng)策劃
- 部隊(duì)防雷電暴雨安全知識(shí)
- 2025年消防文員類(lèi)面試題及答案
- 重慶市名校聯(lián)盟2024-2025學(xué)年高二上學(xué)期第一次聯(lián)合考試物理試題(解析版)
- 船舶駕駛培訓(xùn)虛擬場(chǎng)景構(gòu)建-深度研究
- 手術(shù)患者預(yù)防跌倒
- 《特斯拉汽車(chē)供應(yīng)鏈管理》課件
評(píng)論
0/150
提交評(píng)論