MVCC(多版本并發控制)介紹及實現原理

一、什么是MVCC?

MVCC(Multi-Version Concurrency Control,多版本并發控制)是數據庫中用于解決并發訪問問題的一種機制。它通過為數據維護多個版本,讓讀寫操作在不同版本上獨立進行,從而避免了傳統鎖機制中讀寫沖突導致的性能損耗(如讀操作不會阻塞寫操作,寫操作也不會阻塞讀操作)。

MVCC的核心目標是:在保證事務隔離性的前提下,提高數據庫的并發性能。它廣泛應用于支持行級鎖的數據庫(如MySQL的InnoDB、PostgreSQL等),尤其在讀已提交(Read Committed)可重復讀(Repeatable Read) 隔離級別中發揮關鍵作用。

二、MVCC的實現原理

MVCC的實現依賴于三個核心組件:數據的隱藏列回滾日志(Undo Log)ReadView(讀視圖)。三者協同工作,使得事務能夠訪問到符合其隔離級別的數據版本。

1. 數據的隱藏列

InnoDB存儲引擎會為表中的每一行數據添加三個隱藏列,用于記錄版本信息和事務相關數據:

  • DB_TRX_ID:記錄最后一次修改該行數據的事務ID(6字節)。每次事務對行數據執行INSERT/UPDATE/DELETE操作時,都會將當前事務的ID寫入該列。
  • DB_ROLL_PTR:回滾指針(7字節),指向該行數據的回滾日志(Undo Log),通過該指針可以找到數據的上一個版本。
  • DB_ROW_ID:行ID(6字節),當表沒有主鍵或唯一索引時,InnoDB會用該列生成聚簇索引,確保每行數據有唯一標識。
2. 回滾日志(Undo Log)

回滾日志是MVCC實現多版本的基礎,用于保存數據被修改前的舊版本。

  • 作用
    • 當事務需要回滾時,通過Undo Log恢復數據到修改前的狀態(支持事務的原子性);
    • 為MVCC提供數據的歷史版本,供其他事務讀取(支持并發讀寫)。
  • 生成時機
    當事務執行INSERT/UPDATE/DELETE時,InnoDB會先將數據的舊版本寫入Undo Log,再修改實際數據。
    • INSERT:Undo Log記錄新插入的行信息,事務回滾時直接刪除該行;
    • UPDATE/DELETE:Undo Log記錄修改前的行數據,事務回滾時通過回滾指針恢復舊版本。
  • 版本鏈
    多次修改同一行數據時,Undo Log會形成一條“版本鏈”:每次修改后,新數據的DB_ROLL_PTR指向舊版本的Undo Log,舊版本的DB_ROLL_PTR再指向更早的版本,直至最初版本。

回滾日志為什么在update和delete時不會被立即刪除,而insert之后可以立即刪除?

update和delete之后還會被mvcc或者是快照讀用到**,這里舉個mvcc還需要回滾日志的例子**
MVCC(多版本并發控制)通過回滾日志來實現數據多版本管理,以解決并發事務中的讀 - 寫沖突等問題,在可重復讀隔離級別下體現得較為明顯。以下是一個基于MySQL的InnoDB存儲引擎的例子:

  1. 假設當前有三個事務,事務ID分別為100、200、300。
  2. 事務200先執行了一條SQL語句:UPDATE user SET name = '小王3號' WHERE id = 1,此時數據庫會將修改前的記錄相關信息寫入回滾日志,然后修改實際數據,并將數據的trx_id更新為200。
  3. 接著事務200提交。
  4. 之后事務100開始執行查詢語句,此時會生成一個ReadView,視圖數組為(100, 300)min_id為100,max_id為300。
  5. 然后事務300執行了一條SQL語句:UPDATE user SET name = '小王4號' WHERE id = 1,數據庫同樣會將修改前的記錄(即name = '小王3號')寫入回滾日志,再修改實際數據,將trx_id更新為300。
  6. 此時事務100再次執行查詢語句,根據MVCC的規則:
    • row的trx_id落于min_idmax_id之間,且不在視圖數組中,說明這個版本是已經提交的事務生成的,是可見的。
    • 事務300的trx_id為300,在min_idmax_id之間,但在視圖數組中,所以其修改后的結果對事務100不可見。
    • 事務200的trx_id為200,也在min_idmax_id之間,不在視圖數組中,所以事務100會根據回滾日志找到事務200修改前的記錄,查詢結果為name = '小王3號'

通過這個例子可以看到,MVCC利用回滾日志構建數據的舊版本,配合ReadView機制,讓事務100在事務300已修改數據并提交的情況下,仍然能查詢到符合可重復讀規則的結果,體現了回滾日志在MVCC中的重要作用。

3. ReadView(讀視圖)

ReadView是事務在讀取數據時生成的一個“快照”,用于判斷當前事務能看到哪些版本的數據。它本質上是一組用于過濾數據版本的規則,包含四個核心參數:

  • m_ids:當前活躍(未提交)的事務ID列表。
  • min_trx_id:活躍事務中最小的事務ID。
  • max_trx_id:系統為下一個事務分配的ID(即當前最大事務ID+1)。
  • creator_trx_id:生成該ReadView的事務ID。
4. 版本可見性判斷規則

事務讀取數據時,會根據ReadView的參數,對數據的DB_TRX_ID(最后修改事務ID)進行判斷,決定是否可見:

  1. DB_TRX_ID == creator_trx_id:數據是當前事務自己修改的,可見。
  2. DB_TRX_ID < min_trx_id:修改該數據的事務在當前事務啟動前已提交,可見。
  3. DB_TRX_ID > max_trx_id:修改該數據的事務在當前事務啟動后才開始,不可見(需通過回滾指針找更早版本)。
  4. min_trx_id ≤ DB_TRX_ID ≤ max_trx_id
    • DB_TRX_IDm_ids中(事務仍活躍):不可見(需找更早版本);
    • DB_TRX_ID不在m_ids中(事務已提交):可見。

如果當前版本不可見,事務會通過DB_ROLL_PTR沿著Undo Log的版本鏈向上查找,直到找到符合規則的可見版本。

三、不同隔離級別下的MVCC行為

MVCC的具體表現與事務隔離級別相關,主要差異在于ReadView的生成時機

  • 讀已提交(Read Committed)
    每次執行SELECT時都會重新生成ReadView。因此,事務在兩次查詢之間若有其他事務提交,可能會看到新提交的數據(“不可重復讀”)。
  • 可重復讀(Repeatable Read)
    僅在事務第一次執行SELECT時生成ReadView,之后的查詢復用該ReadView。因此,事務在整個生命周期中看到的數據版本是一致的(“可重復讀”)。
四、MVCC的優勢
  1. 讀寫不沖突:讀操作通過訪問舊版本數據,無需等待寫操作釋放鎖;寫操作僅鎖定當前版本,不影響讀操作。
  2. 隔離級別靈活:通過ReadView的生成時機和版本判斷規則,適配不同隔離級別(讀已提交、可重復讀)。
  3. 支持事務回滾:結合Undo Log,確保事務失敗時數據可恢復(原子性)。
總結

MVCC通過“隱藏列記錄版本”、“Undo Log維護歷史版本鏈”、“ReadView過濾可見版本”三者的配合,實現了多版本數據的并發訪問。它既避免了傳統鎖機制的性能瓶頸,又保證了事務的隔離性,是現代數據庫高效處理并發的核心技術之一。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90148.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90148.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90148.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

密碼學基礎概念詳解:從古典加密到現代密碼體系

一、引言&#xff1a;為什么我們需要密碼學&#xff1f; 在數字化時代&#xff0c;信息已成為核心生產要素&#xff0c;而信息安全則是保障社會運轉的基石。當我們在電商平臺輸入銀行卡密碼時&#xff0c;當我們通過即時通訊工具發送私密消息時&#xff0c;當企業在云端存儲核心…

小鵬汽車視覺算法面試30問全景精解

小鵬汽車視覺算法面試30問全景精解 ——智能駕駛 車路協同 視覺創新:小鵬汽車視覺算法面試核心考點全覽 前言 小鵬汽車作為中國智能電動汽車的創新引領者,致力于通過AI與自動駕駛技術推動智能出行的變革。小鵬視覺算法團隊深耕自動駕駛感知、車路協同、智能座艙、3D重建…

程序是如何生成的-以c語言為例

一&#xff0c;序言 從代碼到能跑的程序&#xff0c;整個過程就像 “把外文翻譯成母語&#xff0c;再組裝成能直接用的東西”&#xff0c;一步步來更清楚&#xff1a; 源代碼&#xff08;程序員寫的代碼&#xff0c;如C語言文件&#xff09;↓ 預處理&#xff08;處理#開頭的命…

風險識別清單:構建動態化的風險管理體系

在項目管理實踐中&#xff0c;風險識別是確保項目成功的關鍵環節。PMBOK提出的風險提示清單&#xff08;Prompt List&#xff09;為項目團隊提供了一個系統化的思考框架&#xff0c;幫助突破個人經驗局限&#xff0c;實現更全面的風險覆蓋。這一工具的價值不僅在于其提供的標準…

從“點狀用例”到“質量生態”:現代軟件測試的演進、困局與破局

測試的三次范式躍遷業務高速迭代下的四大困局質量工程化&#xff1a;流程、平臺、度量三位一體左移與右移&#xff1a;把缺陷扼殺在搖籃&#xff0c;也把監控鋪到墳墓自動化金字塔的再平衡&#xff1a;UI、API、單元、契約、e2e數據驅動測試&#xff1a;從“拍腦袋”到“科學實…

【C++】繼承和多態擴展學習

目錄 1. 菱形虛擬繼承原理剖析 1.1.虛基表 2. 單繼承和多繼承的虛函數表深入探索 2.1 單繼承虛函數表深入探索 2.2 多繼承虛函數表深入探索 ?編輯 2.3 菱形繼承、菱形虛擬繼承 3. 繼承和多態考察的一些常見問題 1. 菱形虛擬繼承原理剖析 繼承的文章中我們講到C的多繼承…

Visual Studio Code 遠端云服務器開發使用指南

目錄 一、下載安裝 1、官方下載 2、下載加速方案 二、基于Ubuntu系統的開發環境搭建方案 1、開發環境配置 2、云服務器架構 3、工作流程關系 4、總結 三、推薦插件 1、免配置插件 1. Remote-SSH - 遠程登錄Linux服務器 2. C/C - 必備的C/C開發插件 3. C/C Extensi…

技術演進中的開發沉思-41 MFC系列:定制 AppWizard

MFC開發&#xff0c;最為重要的無非就是用“MFC AppWizard” 對話框做開發了&#xff0c;第一次使用感覺像拆收音機的孩子 —— 左邊是項目類型選擇&#xff0c;右邊是一堆打勾的選項&#xff0c;點完 “完成”&#xff0c;屏幕上就冒出了能直接編譯運行的窗口程序。那時還不知…

Libevent(3)之使用教程(2)創建事件

Libevent(3)之使用教程(2)創建事件 Author: Once Day Date: 2025年6月29日 一位熱衷于Linux學習和開發的菜鳥&#xff0c;試圖譜寫一場冒險之旅&#xff0c;也許終點只是一場白日夢… 漫漫長路&#xff0c;有人對你微笑過嘛… 本文檔翻譯于&#xff1a;Fast portable non-bl…

Kotlin 作用域函數 let 的實現原理

Kotlin 中的 let 是一個 標準庫擴展函數&#xff0c;它廣泛用于作用域函數&#xff08;Scope Functions&#xff09;中&#xff0c;尤其適用于對可空對象&#xff08;nullable&#xff09;做非空判斷并執行代碼塊的場景。 示例代碼 val name: String? "123" name?…

從FDTD仿真到光學神經網絡:機器學習在光子器件設計中的前沿應用工坊

FDTD仿真與光學神經網絡的基礎概念 FDTD&#xff08;時域有限差分&#xff09;是一種數值方法&#xff0c;用于求解麥克斯韋方程組&#xff0c;廣泛應用于光子器件設計。光學神經網絡通過光波導、衍射元件等物理結構實現矩陣運算&#xff0c;具有低能耗、高并行的優勢。 機器學…

在Ubutu22系統上面離線安裝Go語言環境【教程】

0.引言 Go語言&#xff08;又稱Golang&#xff09;是Google開發的一種靜態強類型、編譯型、并發型編程語言&#xff0c;由Robert Griesemer、Rob Pike和Ken Thompson于2007年開始設計&#xff0c;2009年正式發布。 1.到官網下載壓縮包 2.從win10系統離線上傳壓縮包給ubuntu22…

CMake實踐:CMake3.30版本之前和之后鏈接boost的方式差異

目錄 1.背景 2.boost引入CMake時機 3.CMake 3.30 之前&#xff08;含 3.29&#xff09;鏈接 Boost 的方式 4.CMake 3.30 及之后鏈接 Boost 的方式 5.CMake3.30后引入Boost的步驟 6.遷移建議&#xff08;3.30 之前 → 3.30 之后&#xff09; 7.CMake 3.30 移除FindBoost的…

告別掛馬風險!PBootCMS完美替代方案BadouCMS

開發企業網站時一直比較喜歡用pbootcms,標簽套用很簡單&#xff0c;使用也方便。 但是pbootcms一直有被掛馬的問題&#xff0c;官方好像也不怎么更新了&#xff01;換過好幾個cms&#xff0c;比如eyoucms、dedecms、帝國等等&#xff0c;感覺都不怎么能用得習慣&#xff0c;還…

開發者如何集成AI繪畫?智創聚合API簡化Midjourney接入

在 AI 繪畫領域&#xff0c;Midjourney 的大名如雷貫耳&#xff0c;其強大的圖像生成能力&#xff0c;能將我們腦海中的奇思妙想&#xff0c;迅速轉化為精美的視覺畫面&#xff0c;深受設計師、藝術家以及廣大創意愛好者的青睞。然而&#xff0c;使用 Midjourney 的過程中&…

pycharm回車、刪除、方向鍵和快捷鍵等不能使用原因

解決方法 &#xff1a;菜單欄中的Tools取消勾選Vim Emulator 原因 &#xff1a;新版的pycharm安裝中&#xff0c;默認安裝了vim擴展&#xff0c;一旦安裝了pycharm在編寫代碼時會默認使用Vim編輯器

修復ffmpeg.dll丟失錯誤|6種解決ffmpeg.dll方法詳細教程

看到電腦提示“ffmpeg.dll丟失”&#xff0c;很多人會懵。ffmpeg.dll 是個處理視頻、音頻的關鍵文件。它要是沒了或壞了&#xff0c;軟件就打不開或直接閃退。常見原因是軟件安裝不全、文件被刪、或者中病毒。下面說說它是干嘛的&#xff0c;再給解決辦法。一.ffmpeg.dll 到底是…

OkHttp 與 Stetho 結合使用:打造強大的 Android 網絡調試工具鏈

前言在 Android 應用開發過程中&#xff0c;網絡請求的調試一直是一個重要但具有挑戰性的環節。Facebook 開發的 Stetho 是一個強大的調試工具&#xff0c;當它與 OkHttp 結合使用時&#xff0c;可以為我們提供前所未有的網絡請求洞察能力。本文將詳細介紹如何將這兩者結合使用…

LangGraph教程10:LangGraph ReAct應用

文章目錄 ReAct 預構建的代理 向 ReAct 代理添加記憶 向 ReAct 代理添加系統提示 向 ReAct 代理添加人機交互 ReAct 官方文檔地址:https://langchain-ai.github.io/langgraph/how-tos/#prebuilt-react-agent 中文文檔地址:https://www.aidoczh.com/langgraph/how-tos/#react…

安卓第一個項目

測試所有攝像頭 安卓CameraX&#xff1a;https://developer.android.com/media/grow/spatial-audio?hlzh-cn 1、MainActivity.java // 定義包名 package com.mms.densenapplication;// 引入 AppCompatActivity&#xff0c;支持兼容性更強的 Activity import androidx.appcompa…