欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL回滾日志(undo?log)的作用和使用詳解

 更新時(shí)間:2022年04月15日 11:17:20   作者:每天都要進(jìn)步一點(diǎn)點(diǎn)  
undo?log是innodb引擎的一種日志,在事務(wù)的修改記錄之前,會(huì)把該記錄的原值先保存起來(lái)再做修改,以便修改過(guò)程中出錯(cuò)能夠恢復(fù)原值或者其他的事務(wù)讀取,這篇文章主要給大家介紹了關(guān)于MySQL回滾日志(undo?log)的作用和使用的相關(guān)資料,需要的朋友可以參考下

一、undo log的概念

undo log是mysql中比較重要的事務(wù)日志之一,顧名思義,undo log是一種用于撤銷(xiāo)回退的日志,在事務(wù)沒(méi)提交之前,MySQL會(huì)先記錄更新前的數(shù)據(jù)到 undo log日志文件里面,當(dāng)事務(wù)回滾時(shí)或者數(shù)據(jù)庫(kù)崩潰時(shí),可以利用 undo log來(lái)進(jìn)行回退。

二、undo log的作用

在MySQL中,undo log日志的作用主要有兩個(gè):

1、提供回滾操作【undo log實(shí)現(xiàn)事務(wù)的原子性】

我們?cè)谶M(jìn)行數(shù)據(jù)更新操作的時(shí)候,不僅會(huì)記錄redo log,還會(huì)記錄undo log,如果因?yàn)槟承┰驅(qū)е率聞?wù)回滾,那么這個(gè)時(shí)候MySQL就要執(zhí)行回滾(rollback)操作,利用undo log將數(shù)據(jù)恢復(fù)到事務(wù)開(kāi)始之前的狀態(tài)。

如我們執(zhí)行下面一條刪除語(yǔ)句:

delete from user where id = 1;

那么此時(shí)undo log會(huì)記錄一條對(duì)應(yīng)的insert 語(yǔ)句【反向操作的語(yǔ)句】,以保證在事務(wù)回滾時(shí),將數(shù)據(jù)還原回去。

再比如我們執(zhí)行一條update語(yǔ)句:

update user set name = "李四" where id = 1; ---修改之前name=張三

此時(shí)undo log會(huì)記錄一條相反的update語(yǔ)句,如下:

update user set name = "張三" where id = 1;

如果這個(gè)修改出現(xiàn)異常,可以使用undo log日志來(lái)實(shí)現(xiàn)回滾操作,以保證事務(wù)的一致性。

2、提供多版本控制(MVCC)【undo log實(shí)現(xiàn)多版本并發(fā)控制(MVCC)】

MVCC,即多版本控制。在MySQL數(shù)據(jù)庫(kù)InnoDB存儲(chǔ)引擎中,用undo Log來(lái)實(shí)現(xiàn)多版本并發(fā)控制(MVCC)。當(dāng)讀取的某一行被其他事務(wù)鎖定時(shí),它可以從undo log中分析出該行記錄以前的數(shù)據(jù)版本是怎樣的,從而讓用戶(hù)能夠讀取到當(dāng)前事務(wù)操作之前的數(shù)據(jù)【快照讀】。

下面解釋一下什么是快照讀,與之對(duì)應(yīng)的還有一個(gè)是---當(dāng)前讀。

快照讀:

SQL讀取的數(shù)據(jù)是快照版本【可見(jiàn)版本】,也就是歷史版本,不用加鎖,普通的SELECT就是快照讀。

當(dāng)前讀:

SQL讀取的數(shù)據(jù)是最新版本。通過(guò)鎖機(jī)制來(lái)保證讀取的數(shù)據(jù)無(wú)法通過(guò)其他事務(wù)進(jìn)行修改UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE都是當(dāng)前讀。

三、undo log的存儲(chǔ)機(jī)制

undo log的存儲(chǔ)由InnoDB存儲(chǔ)引擎實(shí)現(xiàn),數(shù)據(jù)保存在InnoDB的數(shù)據(jù)文件中。在InnoDB存儲(chǔ)引擎中,undo log是采用分段(segment)的方式進(jìn)行存儲(chǔ)的。rollback segment稱(chēng)為回滾段,每個(gè)回滾段中有1024個(gè)undo log segment。在MySQL5.5之前,只支持1個(gè)rollback segment,也就是只能記錄1024個(gè)undo操作。在MySQL5.5之后,可以支持128個(gè)rollback segment,分別從resg slot0 - resg slot127,每一個(gè)resg slot,也就是每一個(gè)回滾段,內(nèi)部由1024個(gè)undo segment 組成,即總共可以記錄128 * 1024個(gè)undo操作。

下面以一張圖來(lái)說(shuō)明undo log日志里面到底存了哪些信息?

如上圖,可以看到,undo log日志里面不僅存放著數(shù)據(jù)更新前的記錄,還記錄著RowID、事務(wù)ID、回滾指針。其中事務(wù)ID每次遞增,回滾指針第一次如果是insert語(yǔ)句的話(huà),回滾指針為NULL,第二次update之后的undo log的回滾指針就會(huì)指向剛剛那一條undo log日志,依次類(lèi)推,就會(huì)形成一條undo log的回滾鏈,方便找到該條記錄的歷史版本。

四、undo log的工作原理

在更新數(shù)據(jù)之前,MySQL會(huì)提前生成undo log日志,當(dāng)事務(wù)提交的時(shí)候,并不會(huì)立即刪除undo log,因?yàn)楹竺婵赡苄枰M(jìn)行回滾操作,要執(zhí)行回滾(rollback)操作時(shí),從緩存中讀取數(shù)據(jù)。undo log日志的刪除是通過(guò)通過(guò)后臺(tái)purge線程進(jìn)行回收處理的。

同樣,通過(guò)一張圖來(lái)理解undo log的工作原理。

如上圖:

1、事務(wù)A執(zhí)行update操作,此時(shí)事務(wù)還沒(méi)提交,會(huì)將數(shù)據(jù)進(jìn)行備份到對(duì)應(yīng)的undo buffer,然后由undo buffer持久化到磁盤(pán)中的undo log文件中,此時(shí)undo log保存了未提交之前的操作日志,接著將操作的數(shù)據(jù),也就是Teacher表的數(shù)據(jù)持久保存到InnoDB的數(shù)據(jù)文件IBD。

2、此時(shí)事務(wù)B進(jìn)行查詢(xún)操作,直接從undo buffer緩存中進(jìn)行讀取,這時(shí)事務(wù)A還沒(méi)提交事務(wù),如果要回滾(rollback)事務(wù),是不讀磁盤(pán)的,先直接從undo buffer緩存讀取。

用undo log實(shí)現(xiàn)原子性和持久化的事務(wù)的簡(jiǎn)化過(guò)程:

假設(shè)有A、B兩個(gè)數(shù)據(jù),值分別為1,2。

  • A. 事務(wù)開(kāi)始
  • B. 記錄A=1到undo log中
  • C. 修改A=3
  • D. 記錄B=2到undo log中
  • E. 修改B=4
  • F. 將undo log寫(xiě)到磁盤(pán) -------undo log持久化
  • G. 將數(shù)據(jù)寫(xiě)到磁盤(pán) -------數(shù)據(jù)持久化
  • H. 事務(wù)提交 -------提交事務(wù)

之所以能同時(shí)保證原子性和持久化,是因?yàn)橐韵绿攸c(diǎn):

  1. 更新數(shù)據(jù)前記錄undo log。
  2. 為了保證持久性,必須將數(shù)據(jù)在事務(wù)提交前寫(xiě)到磁盤(pán),只要事務(wù)成功提交,數(shù)據(jù)必然已經(jīng)持久化到磁盤(pán)。
  3. undo log必須先于數(shù)據(jù)持久化到磁盤(pán)。如果在G,H之間發(fā)生系統(tǒng)崩潰,undo log是完整的,可以用來(lái)回滾。
  4. 如果在A - F之間發(fā)生系統(tǒng)崩潰,因?yàn)閿?shù)據(jù)沒(méi)有持久化到磁盤(pán),所以磁盤(pán)上的數(shù)據(jù)還是保持在事務(wù)開(kāi)始前的狀態(tài)。

缺陷:每個(gè)事務(wù)提交前將數(shù)據(jù)和undo log寫(xiě)入磁盤(pán),這樣會(huì)導(dǎo)致大量的磁盤(pán)IO,因此性能較差。 如果能夠?qū)?shù)據(jù)緩存一段時(shí)間,就能減少I(mǎi)O提高性能,但是這樣就會(huì)失去事務(wù)的持久性。

undo日志屬于邏輯日志,redo是物理日志,所謂邏輯日志是undo log是記錄一個(gè)操作過(guò)程,不會(huì)物理刪除undo log,sql執(zhí)行delete或者update操作都會(huì)記錄一條undo日志。

五、undo log的相關(guān)參數(shù)

  • innodb_undo_directory

指定undo log日志的存儲(chǔ)目錄,默認(rèn)值為./。

  •  innodb_undo_logs 

在MySQL5.6版本之后,可以通過(guò)此參數(shù)自定義多少個(gè)rollback segment,默認(rèn)值為128。

  •  innodb_undo_tablespaces 

指定undo log平均分配到多少個(gè)表空間文件中,默認(rèn)值為0,即全部寫(xiě)入一個(gè)文件中。不建議修改為非0值,我們直接使用默認(rèn)值即可。

在InnoDB存儲(chǔ)引擎中,在啟動(dòng)日志中也會(huì)提示:不建議修改 innodb_undo_tablespaces為非0的值。

附錄:參考資料

http://www.dbjr.com.cn/article/244628.htm

http://www.dbjr.com.cn/article/244643.htm

《MySQL技術(shù)內(nèi)幕(第5版)》

到此這篇關(guān)于MySQL回滾日志(undo log)的文章就介紹到這了,更多相關(guān)MySQL回滾日志undo log內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論