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

詳解MySQL事務(wù)日志undo log

 更新時間:2023年07月07日 11:24:54   作者:JAVA旭陽  
眾所周知,事務(wù)的一大特點(diǎn)是原子性,即同一事務(wù)的SQL要同時成功或者失敗,那大家有沒有想過在MySQL的innoDB存儲引擎中是如何保證這樣的原子性操作的,接下來就帶大家一探究竟,感興趣的小伙伴和小編一起來探討吧

undo log介紹

大家不妨先思考下,如果事務(wù)中的SQL執(zhí)行到一半,遇到報錯,需要把前面已經(jīng)執(zhí)行過的SQL撤銷以達(dá)到原子性的目的,這個過程也叫做"回滾",該怎么實(shí)現(xiàn)呢?

每當(dāng)我們要對一條記錄做改動時(這里的改動可以指INSERT、DELETE、UPDATE),把回滾時所需的東西記下來。比如:

  • 你插入一條記錄時,至少要把這條記錄的主鍵值記下來,之后回滾的時候只需要把這個主鍵值對應(yīng)的記錄刪

掉就好了

  • 你刪除了一條記錄,至少要把這條記錄中的內(nèi)容都記下來,這樣之后回滾時再把由這些內(nèi)容組成的記錄插入

到表中就好了

  • 你修改了一條記錄,至少要把修改這條記錄前的舊值都記錄下來,這樣之后回滾時再把這條記錄更新為舊值

MySQL把這些為了回滾而記錄的這些內(nèi)容稱之為撤銷日志或者回滾日志, 即undo log

undo log存儲形式

undo log的日志內(nèi)容是邏輯日志,非物理日志。

  • 物理日志的意思是指具體的把具體某個數(shù)據(jù)頁上的某個偏移量的指改為什么,是具體到物理結(jié)構(gòu)上了,比如redo log就是物理日志。
  • 而邏輯日志只是記錄了某條數(shù)據(jù)的信息是怎么樣的,沒有到具體的物理磁盤上

InnoDBundo log的管理采用段的方式,也就是回滾段(rollback segment) 。每個回滾段記錄了 1024 個 undo log segment ,每個事務(wù)只會使用一個回滾段,當(dāng)一個事務(wù)開始的時候,會制定一個回滾段,在事務(wù)進(jìn)行的過程中,當(dāng)數(shù)據(jù)被修改時,原始的數(shù)據(jù)會被復(fù)制到回滾段。

在MySQL5.5的時候,只有一個回滾段,那么最大同時支持的事務(wù)數(shù)量為1024個。在MySQL 5.6開始,InnoDB支持最大 128個回滾段,故其支持同時在線的事務(wù)限制提高到了 128*1024 。

  • insert undo log格式

記錄的是insert 語句對應(yīng)的undo log,它生成的undo log記錄格式如下圖:

  • update undo log格式

記錄的是update、delete 語句對應(yīng)的undo log,它生成的undo log記錄格式如下圖:

那么上面這些生成undo log日志文件最終是存儲在哪的呢?

這些回滾段是存儲于共享表空間ibdata中。從MySQL5.6版本開始,可通過參數(shù)對rollback segment做進(jìn)一步的設(shè)置。這些參數(shù)包括:

  • innodb_undo_directory: 設(shè)置rollback segment文件所在的路徑。這意味著rollback segment可以存放在共享表空間以外的位置,即可以設(shè)置為獨(dú)立表空間。該參數(shù)的默認(rèn)值為“/”,表示當(dāng)前noDB存儲引擎的目錄。
  • innodb_undo_logs: 設(shè)置rollback segment的個數(shù),默認(rèn)值為128。
  • innodb_undo_tablespaces: 設(shè)置構(gòu)成rollback segment文件的數(shù)量,這樣rollback segment可以較為平均地分布在多個文件中。設(shè)置該參數(shù)后,會在路徑innodb_undo_directory看到undo為前綴的文件,該文件就代表rollback segment文件。

事務(wù)回滾機(jī)制

對于InnoDB引擎來說,每個行記錄除了記錄本身的數(shù)據(jù)之外,還有幾個隱藏的列:

  • DB_ROW_ID:如果沒有為表顯式的定義主鍵,并且表中也沒有定義唯一索引,那么InnoDB會自動為表添加一個row_id的隱藏列作為主鍵。
  • DB_TRX_ID:每個事務(wù)都會分配一個事務(wù)ID,當(dāng)對某條記錄發(fā)生變更時,就會將這個事務(wù)的事務(wù)ID寫入tx_id

中。

  • DB_ROLL_PTR: 回滾指針,本質(zhì)上就是指向undo log的指針。
  • insert數(shù)據(jù):
insert into user (name, sex) values('旭陽', '女')

插入的數(shù)據(jù)都會生成一條insert undo log,并且數(shù)據(jù)的回滾指針會指向它。undo log會記錄undo log的序號、插入主鍵的列和值...,那么在進(jìn)行rollback的時候,通過主鍵直接把對應(yīng)的數(shù)據(jù)刪除即可。

  • update數(shù)據(jù)
update user set sex = '男' where id = 1;
update user set name = 'alvin' where id = 1;

這時會把老的記錄寫入新的undo log,讓回滾指針指向新的undo log,它的undo no是1,并且新的undo log會指向老的undo log(undo no=0),最終形成undo log版本鏈,如下圖所示:

可以發(fā)現(xiàn)每次對數(shù)據(jù)的變更都會產(chǎn)生一個undo log,當(dāng)一條記錄被變更多次時,那么就會產(chǎn)生多條undo log,undo log記錄的是變更前的日志,并且每個undo log的序號是遞增的,那么當(dāng)要回滾的時候,按照序號依次向前推,就可以找到我們的原始數(shù)據(jù)了。

那么按照上面的例子,事務(wù)要進(jìn)行回滾,最終得到下面的執(zhí)行流程:

  • 通過undo no=2的日志把id=1的數(shù)據(jù)的name還原成“旭陽"

  • 通過undo no=1的日志把id=1的數(shù)據(jù)的sex還原成"女"

  • 通過undo no=0的日志把id=1的數(shù)據(jù)根據(jù)主鍵信息刪除

undo log生命周期

生成過程

MySQL處于性能考慮,數(shù)據(jù)會優(yōu)先從磁盤加載到Buffer Pool中,在更新Buffer Pool中數(shù)據(jù)之前,會優(yōu)先將數(shù)據(jù)記錄到undo log中。

記錄undo log日志,MySQL不會直接去往磁盤中的xx.ibdata文件寫數(shù)據(jù),而是會寫在undo_log_buffer緩沖區(qū)中,因?yàn)楣ぷ骶€程直接去寫磁盤太影響效率了,寫進(jìn)緩沖區(qū)后會由后臺線程去刷寫磁盤。

刪除過程

現(xiàn)在我們已經(jīng)明白了undo log日志是如何生成,并且作用于事務(wù)回滾的,那這些數(shù)據(jù)是什么時候刪除呢?

  • 針對于insert undo log,因?yàn)?code>insert操作的記錄,只對事務(wù)本身可見,對其他事務(wù)不可見。故該undo log在事務(wù)提交后就沒有用,就會直接刪除。

● 針對于update undo log,該undo log需要支持MVCC機(jī)制,因此不能在事務(wù)提交時就進(jìn)行刪除。提交時放入undo log鏈表,有專門的purge線程進(jìn)行刪除。

總結(jié)

本文詳細(xì)講解了MySQL中undo log日志的用處,以及它是如何保證事務(wù)的原子性。實(shí)際上,undo log也還有一個很重要的作用就是還對事務(wù)的隔離性實(shí)現(xiàn)起到作用,具體的在后面的MVCC機(jī)制中詳細(xì)說明。如果本文對你有幫助的話,請留下一個贊吧。

以上就是詳解MySQL事務(wù)日志undo log的詳細(xì)內(nèi)容,更多關(guān)于MySQL undo log的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論