首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

深度解析 InnoDB MVCC:行結構、Undo Log、Read View 與「偽 MVCC」本質

     編輯:MySQL 綜合教學

深度解析 InnoDB MVCC:行結構、Undo Log、Read View 與「偽 MVCC」本質

MVCC (Multi-Version Concurrency Control) 是 InnoDB 實現「讀不阻塞寫、寫不阻塞讀」的核心。但 InnoDB 的實現與教科書「理想 MVCC」有本質差異。本文從行結構、Undo Log、Read View 三大支柱切入,還原真實機制。

一、聚簇索引行隱藏列

每行記錄除用戶列外,強制包含 3 個隱藏列(共 23 字節):

隱藏列大小含義
DB_TRX_ID6 字節最後修改該行的事務 ID (單調遞增)
DB_ROLL_PTR7 字節指向 Undo Log 中該行舊版本的回滾指針
DB_ROW_ID6 字節無主鍵時 InnoDB 自動生成的單調遞增行 ID (隱含主鍵)

另有一個 DELETE_BIT 標記刪除標記(非物理刪除)。

二、Undo Log 版本鏈

  • Insert Undo Log:事務對新插入行的回滾信息,事務提交後可立即丟棄(無其他事務可見)。
  • Update Undo Log:修改前的舊行映像,構成版本鏈,供 MVCC 讀取歷史版本。
    更新流程:X Lock 行 → 寫 Redo Log → 寫 Update Undo Log → 修改行值 → 更新 DB_TRX_ID/DB_ROLL_PTR

版本鏈遍歷:DB_ROLL_PTR 串聯所有歷史版本,最新在鏈頭。

三、Read View 可見性判斷

事務啟動時刻建立 Read View(RR 隔離級別僅第一次 SELECT 建立,RC 每次 SELECT 重建),包含:

  • trx_ids[]:當前活躍事務 ID 列表
  • low_limit_id:trx_ids 最小值
  • up_limit_id:系統當前最大事務 ID + 1
  • creator_trx_id:建立 Read View 的事務 ID

可見性算法(針對某行版本的 DB_TRX_ID):

  1. DB_TRX_ID < low_limit_id → 已提交,可見。
  2. DB_TRX_ID >= up_limit_id → 未來事務,不可見。
  3. low_limit_id <= DB_TRX_ID < up_limit_id:
    • DB_TRX_ID IN trx_ids → 活躍事務,不可見(除非是自己 creator_trx_id)。
    • DB_TRX_ID NOT IN trx_ids → 已提交,可見。

RR 下 Read View 固定,實現可重複讀;RC 下每次重建,實現讀已提交。

四、DML 在 MVCC 下的具體動作

操作DB_TRX_IDDB_ROLL_PTRDELETE_BIT新版本
INSERT當前事務 IDNULL0新行插入聚簇索引
DELETE當前事務 ID指向舊版本1標記刪除,不物理移除
UPDATE當前事務 ID指向舊版本0原地修改 + 寫 Undo Log
SELECT不修改不修改不修改順版本鏈找滿足 Read View 的版本

五、InnoDB MVCC vs 理想 MVCC(樂觀鎖)

維度理想 MVCC (樂觀)InnoDB MVCC (悲觀+版本鏈)
修改時加鎖不加鎖,Commit 時比較版本號排他鎖 (X Lock) 鎖定行
衝突檢測Commit 階段版本號比對鎖等待 / 死鎖檢測
多行事務原子性無法保證 (回滾可能覆蓋並發修改)二階段提交 (2PC) + 鎖 保證
讀取阻塞完全無阻塞非鎖定讀 (一致性讀) 無阻塞;鎖定讀 (FOR UPDATE) 阻塞

結論:InnoDB 並非純 MVCC,而是 「行鎖 + 版本鏈」混合模型。之所以仍稱 MVCC,因為它提供了「非鎖定一致性讀」這一核心外部行為。教科書理想 MVCC 在多行事務下無法滿足 ACID,故工程上必須引入鎖。

六、實戰啟示

  1. 長事務危害:Read View 老化導致 Undo Log 無法 Purge,膨脹表空間,拖慢版本鏈遍歷。
  2. 主鍵設計:業務主鍵優於隱含 DB_ROW_ID,避免全表掃描聚簇索引。
  3. RR vs RC:RR 適合報表/一致性讀;RC 適合高併發簡單查詢,但 Binlog 必須 ROW 格式。
  4. Purge 線程:監控 History list length (SHOW ENGINE INNODB STATUS),超萬需關注長事務或 Purge 落後。

理解 MVCC 真實面目,才能在鎖等待、死鎖、Undo 膨脹、主從延遲等疑難雜症中精準定位根因。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved