搜尋
首頁資料庫mysql教程MySQL事務中的redo與undo的分析(圖文)

這篇文章帶給大家的內容是關於MySQL事務中的redo與undo的分析(圖文),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

我們都知道事務有4種特性:原子性、一致性、隔離性和持久性,在事務中的操作,要麼全部執行,要麼全部不做,這就是事務的目的。事務的隔離性由鎖定機制實現,原子性、一致性和持久性由事務的redo 日誌和undo 日誌來保證。所以這篇文章將討論關於事務中的redo和undo的幾個問題:

  • redo 日誌與undo日誌分別是什麼?

  • redo 如何保證交易的持久性?

  • undo log 是否是redo log的逆過程?

redo log

#Redo 的型別

重做日誌(redo log)用來保證事務的持久性,即事務ACID中的D。實際上它可以分成以下兩種類型:

  • 物理Redo日誌

  • #邏輯Redo日誌

在InnoDB儲存引擎中,大部分情況下Redo是實體日誌,記錄的是資料頁的物理變化。而邏輯Redo日誌,不是記錄頁面的實際修改,而是記錄修改頁面的一類操作,例如新建資料頁時,需要記錄邏輯日誌。關於邏輯Redo日誌涉及更底層的內容,這裡我們只需要記住絕大數情況下,Redo是實體日誌即可,DML對頁的修改操作,均需要記錄Redo.

Redo 的作用

Redo log的主要作用是用於資料庫的崩潰復原

Redo 的組成

Redo log可以簡單分成以下兩個部分:

  • 一是記憶體中重做日誌緩衝(redo log buffer),是易失的,在記憶體中

  • 二是重做日誌檔(redo log file ),是持久的,保存在磁碟中

什麼時候寫Redo?

上面那張圖簡單地體現了Redo的寫入流程,這裡再細說下寫入Redo的時機:

  • 在資料頁修改完成之後,在髒頁刷出磁碟之前,寫入redo日誌。注意的是先修改數據,後寫日誌

  • redo日誌比數據頁先寫回磁碟

  • 聚集索引、二級索引、undo頁面的修改,均需記錄Redo日誌。

Redo的整體流程

下面以更新交易為例,在宏觀上掌握redo log 流轉過程,如下圖所示:

MySQL事務中的redo與undo的分析(圖文)

  • 第一步:先將原始資料從磁碟中讀入記憶體中來,修改資料的記憶體拷貝

  • #第二步:產生一條重做日誌並寫入redo log buffer,記錄的是資料被修改後的值

  • 第三步:當交易commit時,將redo log buffer中的內容刷新到redo log file,對redo log file採用追加寫的方式

  • 第四步:定期將記憶體中修改的資料刷新到磁碟中

redo如何保證交易的持久性?

InnoDB是交易的儲存引擎,其透過Force Log at Commit 機制實現交易的持久性,即當交易提交時,先將redo log buffer 寫入到redo log file 進行持久化,待交易的commit作業完成時才算完成。這種做法也稱為 Write-Ahead Log(預先日誌持久化),在持久化一個資料頁之前,先將記憶體中對應的日誌頁持久化。

為了確保每次日誌都寫入redo log file,在每次將redo buffer寫入redo log file之後,預設情況下,InnoDB儲存引擎都需要呼叫一次fsync操作 ,因為重做日誌開啟並沒有O_DIRECT選項,所以重做日誌先寫入到檔案系統快取。為了確保重做日誌寫入到磁碟,必須進行一次 fsync操作。 fsync是一種系統呼叫操作,其fsync的效率取決於磁碟的效能,因此磁碟的效能也影響了交易提交的效能,也就是資料庫的效能。
(O_DIRECT選項是在Linux系統中的選項,使用該選項後,對檔案進行直接IO操作,不經過檔案系統緩存,直接寫入磁碟)

##上面提到的

Force Log at Commit機制就是靠InnoDB儲存引擎提供的參數innodb_flush_log_at_trx_commit來控制的,該參數可以控制redo log刷新到磁碟的策略,設定該參數值也可以允許使用者設定非持久性的情況發生,具體如下:

  • 當設定參數為1時,(預設為1),表示交易提交時必須呼叫一次

    fsync 操作,最安全的配置,保障持久性

  • 當設定參數為2時,則在交易提交時只做write 操作,只保證將redo log buffer寫到系統的頁面快取中,不進行fsync操作,因此如果MySQL資料庫宕機時不會遺失事務,但作業系統宕機則可能遺失事務

  • 當設定參數為0時,表示交易提交時不進行寫入redo log操作,這個操作僅在master thread 完成,而在master thread每1秒進行一次重做日誌的fsync操作,因此實例crash 最多遺失1秒鐘內的交易。 (master thread是負責將緩衝池中的資料非同步刷新到磁碟,保證資料的一致性)

#fsyncwrite操作其實是系統呼叫函數,在許多持久化場景都有使用到,例如Redis 的AOF持久化中也使用到兩個函數。 fsync操作將資料提交到硬碟中,強制硬碟同步,將一直阻塞到寫入硬碟完成後返回,大量進行fsync操作就有效能瓶頸,而write 操作將資料寫到系統的頁面快取後立即返回,後面依靠系統的調度機制將快取資料刷到磁碟中去,其順序是user buffer——> page cache——>disk。

MySQL事務中的redo與undo的分析(圖文)

除了上面談到的Force Log at Commit機制保證交易的持久性,實際上重做日誌的實作還要依賴於mini-transaction。

Redo在InnoDB中是如何實現的?與mini-transaction的聯繫?

Redo的實作實際上跟mini-transaction緊密相關,mini-transaction是一種InnoDB內部使用的機制,透過mini-transaction來保證並發事務操作下以及資料庫異常時資料頁中數據的一致性,但它不屬於事務。

為了使得mini-transaction保證資料頁資料的一致性,mini-transaction必須遵循以下三種協定

  • The FIX Rules

  • Write-Ahead Log

  • #Force-log-at-commit

## The FIX Rules

修改一個資料頁時需要取得該頁的x-latch(排他鎖),取得一個資料頁時需要該頁的s-latch(讀鎖定或稱為共用鎖) 或是x-latch,持有該頁的鎖直到修改或存取該頁的操作完成。

Write-Ahead Log

在前面闡述中就提到了Write-Ahead Log(預先寫日誌)。在持久化一個資料頁之前,必須先將記憶體中對應的日誌頁持久化。每個頁都有一個LSN(log sequence number),代表日誌序號,(LSN佔用8字節,單調遞增), 當一個資料頁需要寫入到持久化設備之前,要求記憶體中小於該頁LSN的日誌先寫入持久化設備

那為什麼必須先寫日誌呢?可不可以不寫日誌,直接將資料寫入磁碟?原則上是可以的,只不過會產生一些問題,資料修改會產生隨機IO,但日誌是順序IO,append方式順序寫,是一種串列的方式,這樣才能充分利用磁碟的效能。

Force-log-at-commit

這一點也就是前文提到的如何保證事務的持久性的內容,這裡再次總結一下,與上面的內容相呼應。在一個交易中可以修改多個頁,Write-Ahead Log 可以保證單一資料頁的一致性,但無法保證交易的持久性,Force-log-at-commit 要求當一個交易提交時,其產生所有的mini -transaction 日誌必須刷新到磁碟中,若日誌刷新完成後,在緩衝池中的頁刷新到持久化儲存裝置前資料庫發生了宕機,那麼資料庫重新啟動時,可以透過日誌來保證資料的完整性。

重做日誌的寫入流程

MySQL事務中的redo與undo的分析(圖文)

#上圖表示了重做日誌的寫入流程,每個mini-transaction對應每一條DML操作,例如一條update語句,其由mini-transaction來保證,對資料修改後,產生redo1,首先將其寫入mini-transaction私有的Buffer中,update語句結束後,將redo1從私有Buffer拷貝到公有的Log Buffer。當整個外部交易提交時,將redo log buffer再刷入到redo log file中。

undo log

undo log的定義

undo log主要記錄的是資料的邏輯變化,為了在發生錯誤時回滾之前的操作,需要將先前的操作都記錄下來,然後在發生錯誤時才可以回滾。

undo log的作用

undo是一種邏輯日誌,有兩個作用:

  • 用於交易的回滾

  • MVCC

關於MVCC(多版本並發控制)的內容這裡就不多說了,本文將重點放在undo log用於交易的回溯。

undo日誌,只將資料庫邏輯地恢復到原來的樣子,在回滾的時候,它實際上是做的相反的工作,比如一條INSERT ,對應一條DELETE,對於每個UPDATE,對應一條相反的UPDATE,將修改前的行放回去。 undo日誌用於交易的回滾操作進而保障了交易的原子性。

undo log的寫入時機

  • DML作業修改叢集索引前,記錄undo日誌

  • 二級索引記錄的修改,不記錄undo日誌

要注意的是,undo頁面的修改,同樣需要記錄redo日誌。

undo的儲存位置

在InnoDB儲存引擎中,undo儲存在回滾區段(Rollback 在Segment)中,每個回滾段記錄了1024個undo log segment,而在每個undo log segment段中進行undo 頁的申請,在5.6以前,Rollback Segment是在共享表空間裡的,5.6.3之後,可透過 innodb_undo_tablespace設定undo儲存的位置。

undo的類型

##在InnoDB儲存引擎中,undo log分為:

  • insert undo log

  • update undo log

insert undo log是指在insert 操作中產生的undo log,因為insert操作的記錄,只對事務本身可見,對其他事務不可見。故該undo log可以在交易提交後直接刪除,不需要進行purge操作。

而update undo log記錄的是對delete 和update操作產生的undo log,該undo log可能需要提供MVCC機制,因此不能再交易提交時就進行刪除。提交時放入undo log鍊錶,等待purge執行緒進行最後的刪除。

補充:purge執行緒兩個主要作用是:清理undo頁和清除page裡面有Delete_Bit標識的資料行。在InnoDB中,交易中的Delete操作其實不是真正的刪除資料行,而是一種Delete Mark操作,在記錄上標識Delete_Bit,而不刪除記錄。是一種"假刪除",只是做了個標記,真正的刪除工作需要後台purge線程去完成。

undo log 是否是redo log的逆過程?

undo log 是否是redo log的逆過程?其實從前文就可以得出答案了,undo log是邏輯日誌,對事務回滾時,只是將資料庫邏輯地恢復到原來的樣子,而redo log是實體日誌,記錄的是資料頁的實體變化,顯然undo log不是redo log的逆過程。

redo & undo總結

以下是redo log undo log的簡化過程,以便於理解兩種日誌的過程:

假设有A、B两个数据,值分别为1,2.
1. 事务开始
2. 记录A=1到undo log
3. 修改A=3
4. 记录A=3到 redo log
5. 记录B=2到 undo log
6. 修改B=4
7. 记录B=4到redo log
8. 将redo log写入磁盘
9. 事务提交
實際上,在insert/update/delete操作中,redo和undo分別記錄的內容都不一樣,量也不一樣。在InnoDB記憶體中,一般的順序如下:

  • 寫undo的redo

  • 寫undo

  • ##修改資料頁
  • 寫Redo
#小結

本文分析了事務中的redo和undo日誌,參考了一些資料書整理得出,可能有些地方表述的不清楚。如有不對之處,歡迎指出。

#

以上是MySQL事務中的redo與undo的分析(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除
MySQL:初學者的基本技能MySQL:初學者的基本技能Apr 18, 2025 am 12:24 AM

MySQL適合初學者學習數據庫技能。 1.安裝MySQL服務器和客戶端工具。 2.理解基本SQL查詢,如SELECT。 3.掌握數據操作:創建表、插入、更新、刪除數據。 4.學習高級技巧:子查詢和窗口函數。 5.調試和優化:檢查語法、使用索引、避免SELECT*,並使用LIMIT。

MySQL:結構化數據和關係數據庫MySQL:結構化數據和關係數據庫Apr 18, 2025 am 12:22 AM

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

MySQL:解釋的關鍵功能和功能MySQL:解釋的關鍵功能和功能Apr 18, 2025 am 12:17 AM

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。

SQL的目的:與MySQL數據庫進行交互SQL的目的:與MySQL數據庫進行交互Apr 18, 2025 am 12:12 AM

SQL用於與MySQL數據庫交互,實現數據的增、刪、改、查及數據庫設計。 1)SQL通過SELECT、INSERT、UPDATE、DELETE語句進行數據操作;2)使用CREATE、ALTER、DROP語句進行數據庫設計和管理;3)複雜查詢和數據分析通過SQL實現,提升業務決策效率。

初學者的MySQL:開始數據庫管理初學者的MySQL:開始數據庫管理Apr 18, 2025 am 12:10 AM

MySQL的基本操作包括創建數據庫、表格,及使用SQL進行數據的CRUD操作。 1.創建數據庫:CREATEDATABASEmy_first_db;2.創建表格:CREATETABLEbooks(idINTAUTO_INCREMENTPRIMARYKEY,titleVARCHAR(100)NOTNULL,authorVARCHAR(100)NOTNULL,published_yearINT);3.插入數據:INSERTINTObooks(title,author,published_year)VA

MySQL的角色:Web應用程序中的數據庫MySQL的角色:Web應用程序中的數據庫Apr 17, 2025 am 12:23 AM

MySQL在Web應用中的主要作用是存儲和管理數據。 1.MySQL高效處理用戶信息、產品目錄和交易記錄等數據。 2.通過SQL查詢,開發者能從數據庫提取信息生成動態內容。 3.MySQL基於客戶端-服務器模型工作,確保查詢速度可接受。

mysql:構建您的第一個數據庫mysql:構建您的第一個數據庫Apr 17, 2025 am 12:22 AM

構建MySQL數據庫的步驟包括:1.創建數據庫和表,2.插入數據,3.進行查詢。首先,使用CREATEDATABASE和CREATETABLE語句創建數據庫和表,然後用INSERTINTO語句插入數據,最後用SELECT語句查詢數據。

MySQL:一種對數據存儲的初學者友好方法MySQL:一種對數據存儲的初學者友好方法Apr 17, 2025 am 12:21 AM

MySQL適合初學者,因為它易用且功能強大。 1.MySQL是關係型數據庫,使用SQL進行CRUD操作。 2.安裝簡單,需配置root用戶密碼。 3.使用INSERT、UPDATE、DELETE、SELECT進行數據操作。 4.複雜查詢可使用ORDERBY、WHERE和JOIN。 5.調試需檢查語法,使用EXPLAIN分析查詢。 6.優化建議包括使用索引、選擇合適數據類型和良好編程習慣。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)