MySQL - 事務原理
一、概述
1.1 什么是事務?
事務是一組操作的集合,它是一個不可分割的工作單位,事務會把所有的操作作為一個整體一起向系統提交或撤銷操作請求,即這些操作:要么同時成功,要么同時失敗
1.2 事務的特性:ACID
- 原子性(Atomicity):事務是不可分割的最小操作單元,要么全部成功,要么全部失敗
- 一致性(Consistency):事務完成時候,必須使所有的數據都保持一直狀態
- 隔離性(Isolation):數據庫系統提供的隔離機制,保證事務在不受外部并發操作影響的獨立環境下運行
- 持久性(Durability):事務一旦提交或回滾,它對數據庫中的數據的改變就是永久的
1.3 事務四大特性的實現

原子性/一致性/持久性:通過Redo Log和Undo Log實現
隔離性:通過鎖+MVCC實現
二、Redo Log(重做日志)
Redo Log主要用來實現四大特性中的"持久性"
重做日志,記錄的是事務提交時數據頁的物理修改,該日志文件由兩部分組成:
重做日志緩沖(redo log buffer)以及重做日志文件(redo log file),前者是在內存中,后者在磁盤中,當事務提交之后會把所有修改信息都存到該日志文件中,用于在刷新臟頁到磁盤,發生錯誤時,進行數據恢復使用

- 客戶端發起UPDATE/DELETE請求到InnoDB存儲引擎 Buffer Pool緩沖池
- 判斷緩沖池中是否存在數據,如果有,則直接進行修改,如果沒有,則通過后臺線程讀取磁盤中的數據文件到緩沖池
- 在緩沖池直接進行SQL操作,這時候Buffer Pool中是更新好的數據,數據文件中是老的數據,我們稱Buffer Pool中的頁為臟頁
- 將增刪改的數據現記錄到Redo Log Buffer中,里面記錄的是數據頁的物理變化
- 事務提交時,將Redo Log Buffer中的變化刷新到磁盤當中,生成Redo Log日志文件
- 過一定時間,進行臟頁刷新
2.1 Redo Log的實現
- 物理日志: Redo Log 是物理日志,記錄的是物理數據頁的更改,而不是 SQL 操作或邏輯操作。它記錄了數據庫物理塊的變更,比如某個數據頁上某條記錄的修改。
- WAL(Write-Ahead Logging)機制: InnoDB 采用 WAL 機制,即先寫日志,再寫磁盤。每次事務提交時,InnoDB 會將 Redo Log 先寫入磁盤,而后再慢慢將實際修改的數據寫入磁盤。
- 循環寫機制: Redo Log 采用固定大小的循環寫機制。當日志寫滿時,會從頭開始重新寫。因此,在系統運行時,InnoDB 會定期將日志應用到數據頁,并將臟頁(即被修改但還未寫入磁盤的數據頁)刷新到磁盤。
2.2 為什么要先把Redo Log刷新到磁盤當中?
分為兩種場景:
場景一:如果過一定時間在刷新臟頁,如果刷新失敗,則無法保證數據的持久性
場景二:如果每次寫入都直接刷新到磁盤,這樣存在嚴重的性能問題
如果直接刷新,涉及大量的隨機磁盤IO,性能比較低,如果用到Redo Log,不會直接刷新臟頁,Redo Log日志文件是追加寫入,順序磁盤IO
2.3 Redo Log的使用場景
- 崩潰恢復: 當數據庫崩潰后,通過重啟,MySQL 可以根據 Redo Log 恢復所有已提交的事務。這是 MySQL 保證事務持久性的關鍵機制。
- 提高性能: 因為 Redo Log 可以先于數據頁寫入磁盤,數據庫無需每次事務提交時都立即寫入數據頁,從而顯著提高了寫操作的性能。數據頁的寫入可以在稍后的時間由后臺線程異步完成。
三、Undo Log(回滾日志)
Undo Log主要用來實現四大特性中的"原子性"
回滾日志,用于記錄數據被修改前的信息,作用包含兩個:提供回滾和MVCC(多版本并發控制),undo log和redo log記錄物理日志不一樣,它是邏輯日志
undo log銷毀: undo log在事務執行時產生,事務提交時,并不會立即刪除undo log,因為這些日志可能還用于MVCC
undo log存儲: undo log采用段的方式進行管理和記錄,存存放在前面介紹的rollback segment回滾段中,內部包含1024個undo log segment
3.1 Undo Log的實現
- 邏輯日志: Undo Log是一種邏輯日志,記錄的是邏輯上的修改操作,它并不會直接記錄每次操作的物理存儲修改,而是記錄修改前的數據
- 鏈表結構: InnoDB存儲引擎會為每條記錄維護一條Undo Log記錄,并以鏈表的方式串聯起來,如果事務需要回滾,MySQL會沿著Undo Log鏈表進行逐條回滾,直至恢復到事務開始時的狀態
- Undo Log記錄類型:
- 對于
INSERT操作: Undo Log記錄的是“刪除”操作,因為如果事務回滾,需要撤銷插入的數據 - 對與
DELETE操作: Undo Log記錄的是“插入”操作,用來恢復被刪除的數據 - 對于
UPDATE操作: Undo Log記錄的是修改前的舊值,用來恢復原來的值
- 對于
3.2 使用場景
- 事務回滾: 當事務執行失敗或用戶顯式要求回滾時,Undo Log 會將所有修改的數據恢復到事務開始前的狀態
- MVCC(多版本并發控制): Undo Log 也用于實現 MVCC 機制,不同事務可能在不同時間看到不同版本的數據,這些版本的數據就是由 Undo Log 提供的。這樣,未提交的事務修改對其他事務是不可見的,幫助實現隔離性
四、Redo Log和Undo Log的區別
| 對比項 | Undo Log | Redo Log |
|---|---|---|
| 作用 | 記錄數據的舊值,用于回滾事務 | 記錄數據的修改,用于恢復已提交的事務 |
| 日志類型 | 邏輯日志,記錄邏輯操作 | 物理日志,記錄數據頁的物理修改 |
| 實現機制 | 鏈表結構,逐條回滾 | 固定大小的循環寫機制,WAL 策略 |
| 使用場景 | 事務回滾、多版本并發控制(MVCC) | 崩潰恢復、保證數據持久性 |
| 何時寫入磁盤 | 修改數據時記錄,但無需立即寫入磁盤 | 事務提交時必須寫入磁盤 |
| 涉及的 ACID 特性 | 原子性、隔離性 | 持久性 |

浙公網安備 33010602011771號