MySQL InnoDB 的 MVCC 機制

前言

????????多版本并發控制(MVCC)是 MySQL InnoDB 存儲引擎實現高性能事務的核心機制。它通過創建數據快照,使得讀寫操作可以無鎖并發,極大地提升了數據庫的并發性能。本文將深入探討 MVCC 的工作原理、實現細節以及它與事務隔離級別的緊密關系。

一、 MVCC 要解決什么問題?

????????在高并發場景下,數據庫事務處理主要面臨三種操作組合:

  • 讀-讀:無需任何控制,不會產生問題。

  • 寫-寫:必須通過加鎖(行鎖、表鎖等)實現串行化,保證數據一致性。

  • 讀-寫:如果采用加鎖的方式,讀操作會阻塞寫操作,寫操作也會阻塞讀操作,嚴重影響并發性能。

MVCC 的終極目標就是優雅地解決 讀-寫沖突,實現無鎖的非阻塞并發讀

二、 MVCC 的實現基石

????????MVCC 的實現依賴于兩個核心部分:數據的版本鏈事務的讀視圖 (Read View)

  1. 數據的版本鏈 (Undo Log) InnoDB 的每行記錄中都包含兩個重要的隱藏字段:

    • DB_TRX_ID (6字節):記錄最后一次插入或更新該行數據的事務 ID。

    • DB_ROLL_PTR (7字節):回滾指針,指向該行數據的前一個版本(存儲在 Undo Log 中)。 每次對記錄進行更新時,都會將舊值寫入 Undo Log,然后 DB_ROLL_PTR 會形成一個指向舊版本記錄的鏈表,即版本鏈。鏈首是最新的記錄,鏈尾是最舊的記錄。

  2. 事務的讀視圖 (Read View) Read View 是事務在執行快照讀(普通 SELECT 語句)時產生的讀視圖,它決定了當前事務能看到哪個版本的數據。 它主要包含以下關鍵屬性:

    • m_ids:創建 Read View 時,系統中所有活躍(尚未提交)事務的事務 ID 集合。

    • min_trx_id:m_ids 集合中的最小值。

    • max_trx_id:創建 Read View 時,系統尚未分配的下一個事務 ID(并非 m_ids 中的最大值)。

    • creator_trx_id:創建該 Read View 的事務的事務 ID。

三、 可見性算法

????????有了版本鏈和 Read View,就可以根據以下規則判斷某個版本的記錄是否對當前事務可見:

  1. 如果數據版本的 DB_TRX_ID 小于 min_trx_id,說明該版本在 Read View 創建前已提交,可見

  2. 如果數據版本的 DB_TRX_ID 大于等于 max_trx_id,說明該版本是由在 Read View 創建之后才啟動的事務生成的,不可見。需要沿著版本鏈繼續查找舊版本。

  3. 如果數據版本的 DB_TRX_ID[min_trx_id, max_trx_id) 區間內:

    • DB_TRX_ID m_ids 集合中,說明創建 Read View 時該事務仍活躍,其修改不可見

    • DB_TRX_ID 不在 m_ids 集合中,說明創建 Read View 時該事務已提交,其修改可見

  4. 如果當前記錄對自己的事務做了修改(DB_TRX_ID == creator_trx_id),那么該版本總是可見的。

四、 MVCC 與隔離級別

????????MVCC 的行為因事務隔離級別而異,核心區別在于 Read View 的生成時機

  • READ COMMITTED (讀已提交)每次執行快照讀時都會生成一個新的 Read View。這會導致每次讀都能看到其他事務已提交的最新修改,從而產生“不可重復讀”現象。

  • REPEATABLE READ (可重復讀):只在第一次執行快照讀時生成一個 Read View,后續所有讀操作都復用這個視圖。這就保證了在整個事務過程中,看到的數據內容是一致的,實現了可重復讀。

五、說人話(個人理解)

????????對于Mysql的MVCC他解決的問題是在事務并發情況下,對于讀+寫操作的無鎖解決方案。

????????在事務并發場景下會出現讀+讀、讀+寫、寫+寫這三種組合,其中對于讀+讀是無需干預的,能夠保證并發場景下數據的一致性以及隔離性。對于寫+寫操作就需要按照一定次序串行執行了,對于該問題就需要鎖來實現,如果不加鎖的話是無法保證數據的一致性以及隔離性的。這個問題不在MVCC討論的范疇中,主要解決方式與Mysql的鎖相關。此處不再贅述。對于讀+寫操作在解決方案上可以通過鎖來保證數據的一致性但是加鎖就會導致鎖的競爭問題進而影響整體Mysql的并發度問題導致命令執行效率下降。此時MVCC機制就實現了無鎖的情況下舍棄數據實時性為代價提高事務并發效率。因為在一定場景下可以接受數據出現一定程度的不一致問題,因此可以犧牲此部分來追求并發度的提升。

????????對于MVCC機制他的實現基礎,即立足點是針對數據表中的數據進行不同版本的控制,針對數據不同版本判斷各個事務對于數據的可見性。即事務對應的版本對應所查詢的數據的版本是否合理。進而引出了快照讀這個操作。上述兩個關鍵點:”事務的版本”和“數據的版本”是MVCC機制實現的基礎。

????????其中數據的版本通過每行數據中幾個隱藏字段進行標識:trx_id字段標識了最后一次修改/增加改行數據的事務id。roll_pointer字段指向該行數據上個版本的數據信息。在事務執行過程中會將這些信息記錄到undo log日志中,通過該日志可以實現事務回滾以及MVCC。

????????事務的版本控制通過建立readview來控制。readview包含信息為:m_ids記錄了當前readview創建時刻所有活躍的事務(已創建但是未提交的事務)。min_trx_id記錄創建readview時最小的活躍事務id。max_trx_id記錄創建readview時最大的活躍事務id。create_trx_id記錄創建readview時分配給當前事務的id,該字段為全局自增字段。通過trx_id和roll_pointor字段可以對數據建立一個版本鏈。然后每個事務的readview為該事務創建時刻對當前數據庫事務處理情況的一個快照,通過對比當前事務需要查詢的數據版本鏈信息可以得出當前事務可見的數據版本。

????????這個具體的規則為:當數據trx_id小于事務readview的min_trx_id時,證明此時數據行最后一次修改的事務是在當前事務創建之前就已經提交了,所以是合理的,因此是對于該事務而言是可見的。當trx_id大于事務readview的max_trx_id時,證明此時數據行最后一次修改的事務是在事務創建之后又新建的事務,此時在時間線上該數據行的版本是先于當前事務的,所以該數據行對于事務而言是不可見的,需要通過roll_pointor字段查詢舊版本的數據行。如果trx_id位于readview的min_trx_id和max_trx_id之間時,證明此數據行最后一次修改的事務是與當前事務是位于同一時間線的,證明是同一版本,但是修改該數據行的事務是否提交這個還需要判斷,因此進一步判斷該trx_id是否存在于m_ids列表中,如果存在,證明這兩個事務都是活躍的,此時不能保證該數據行是否修改完成,所以是不可見的。而如果不存在m_ids列表中時,證明修改該數據行的事務已經提交,此時是可見的。

????????而對應MVCC的控制也有級別之分。其中就是可重復讀級別和讀已提交級別。 對于兩者的區別是兩者的readview創建時機不同。其中讀已提交級別他的readview創建是在每一次快照讀時都會重新創建,更新其中的m_ids等字段,此時他的并發程度更高,因為該級別每一次快照讀都會放大數據行的版本可見區間。但是會在數據一致性上帶來不可重復讀的問題,也就是一個事務兩次讀取同一數據不一致的問題。因為他在每次快照讀時都會重建readview,如果第一次和第二次查詢期間有其他事務提交對任務的修改,此時就會出現不可重復讀的問題。而可重復讀的readview創建時機是在事務第一次創建時進行創建,后續不會新建。此時對于可重復讀隔離級別而言他的快照讀操作就定格在了事務創建的那一刻了,此時就算有其他事務在第一次查詢和第二次查詢期間他都只會查詢到第一次的數據行,因為第二次的數據行對于該隔離級別而言是不可見的。但是也會有一定問題就是幻讀問題。

?更多資料:0voice · GitHub

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

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

相關文章

景區負氧離子氣象站:引領綠色旅游,暢吸清新每一刻

在綠色旅游成為消費主流的今天,游客對 “清新空氣” 的需求不再是模糊的期待,而是可感知、可選擇的具體體驗。景區負氧離子氣象站的出現,正以科技之力重塑綠色旅游格局,讓 “暢吸清新每一刻” 從口號變為觸手可及的現實&#xff0…

Pytorch筆記一之 cpu模型保存、加載與推理

Pytorch筆記一之 cpu模型保存、加載與推理 1.保存模型 首先,在加載模型之前,我們需要了解如何保存模型。PyTorch 提供了兩種保存模型的方法:保存整個模型和僅保存模型的狀態字典(state dict)。推薦使用第二種方式&…

當AI在代碼車間組裝模塊:初級開發者的創意反成「核心算法」

前言:哈嘍,大家好,今天給大家分享一篇文章!并提供具體代碼幫助大家深入理解,徹底掌握!創作不易,如果能幫助到大家或者給大家一些靈感和啟發,歡迎收藏關注哦 💕 目錄當AI在…

技術視界 | 跨域機器人通信與智能系統:打破壁壘的開源探索

8 月 16 日,在 OpenLoong 社區舉辦的第九期線下分享會上,國家地方共建人形機器人創新中心的軟件開發負責人 Amadeus 博士帶來了一場主題為“跨域機器人通信與智能系統:打破行業壁壘的創新方案”的演講。深入探討了當前機器人領域的一個關鍵痛…

Android入門到實戰(八):從發現頁到詳情頁——跳轉、傳值與RecyclerView多類型布局

一. 引言在上一篇文章里,我們從零開始實現了 App 的 發現頁面,通過網絡請求獲取數據,并使用 RecyclerView 展示了劇集列表。但光有發現頁還不夠,用戶在點擊一部劇時,自然希望進入到一個更詳細的頁面,去查看…

【工具】41K star!網頁一鍵變桌面應用

項目中遇到了一個需要將現有的 web 頁面打包成一個 桌面應用 的需求。 最一開始想到的是 Electron,但是它還需要一些開發工作并且打包后的應用體積比較大,調研后發現了開源工具 Pake。 它能讓你用最輕量的方式,把任何網頁一鍵打包成跨平臺桌…

浪潮CD1000-移動云電腦-RK3528芯片-2+32G-安卓9-2種開啟ADB ROOT刷機教程方法

浪潮CD1000-移動云電腦-RK3528芯片-232G-安卓9-2種開啟ADB ROOT刷機教程方法 往期文章: 浪潮CD1000-移動云電腦-RK3528芯片-232G-安卓9-開啟ADB ROOT破解教程 地址1:浪潮CD1000-移動云電腦-RK3528芯片-232G-開啟ADB ROOT破解教程-CSDN博客 中國移動浪潮…

Day23_【機器學習—聚類算法—K-Means聚類 及評估指標SSE、SC、CH】

一、聚類算法概念屬于無監督學習算法,即有特征無標簽,根據樣本之間的相似性,將樣本劃分到不同的類別中。所謂相似性可以理解為歐氏距離、曼哈頓距離、切比雪夫距離... 。分類按顆粒度分為:粗聚類、細聚類。按實現方法分為&#xf…

android seekbar顯示刻度

SeekBar簡介 SeekBar是Android中的一個可交互UI組件,允許用戶通過拖動滑塊在特定范圍內選擇數值。繼承自ProgressBar,但增加了用戶手動調節功能,常用于音量控制、亮度調節等場景。 核心屬性 android:maxHeight // 背景高度 android:progres…

【高并發內存池】五、頁緩存的設計

文章目錄Ⅰ. page cache頁緩存的結構設計Ⅱ. 完善central cache中的 get_span() 函數Ⅲ. 實現頁緩存獲取span對象的接口Ⅰ. page cache頁緩存的結構設計 ? 首先頁緩存還是一個哈希桶的結構,但是和前兩者不同的是,頁緩存的哈希桶中存放的是一個或者多個…

Elasticsearch(text和keyword)區別分析

text:全文檢索類型,經過分詞處理,支持模糊匹配? keyword:精確匹配類型,適用于聚合、排序和過濾? text 1. 核心屬性 ?analyzer屬性?: 指定用于索引和搜索的分詞器 默認使用標準分析器(Standard Analyzer) 示例:"analyzer": "ik_max_word"(中文…

通過tailscale實現一臺電腦上vscode通過ssh連接另一臺電腦上的VMware Linux 虛擬機

當需要通過一臺windows電腦上的vscode來ssh連接另一臺電腦上的linux虛擬機進行遠程操作,可以通過tailscale來實現。 Linux虛擬機上安裝tailscale 由于掛代理下載仍然很慢,而清華鏡像源又沒有tailscale的軟件包,所以可以通過下載 DEB 包安裝…

[Upscayl圖像增強] docs | 前端 | Electron工具(web->app)

鏈接:https://upscayl.org/docs:Upscayl Upscayl是一款桌面應用程序,允許用戶使用人工智能放大和增強圖像。 提供了一個用戶友好的圖形界面(渲染器用戶界面),用戶可以選擇圖像或文件夾,從多種AI…

阿里云通義MoE全局均衡技術:突破專家負載失衡的革新之道

MoE模型的基本原理與核心價值 混合專家模型(Mixture of Experts,MoE)是當前AI大模型領域最重要的架構創新之一,其核心思想是通過多個“專家”網絡協同處理輸入數據,并由門控網絡動態選擇或組合各個專家的輸出&#xf…

macOS中設置環境變量的各文件及作用域

在 macOS 中,~/.zshrc 和 ~/.bash_profile 是 Shell 的配置文件,用于設置環境變量、命令別名、啟動命令等。它們在你每次打開終端時會被自動加載。文件對應 Shell作用~/.zshrcZsh(macOS Catalina 及以后默認)每次打開新的終端窗口…

【華為培訓筆記】OptiX OSN 9600 設備保護專題

OptiX OSN 9600 設備保護專題 1、光層保護 定義 方式 應用

Python開篇撬動未來的萬能鑰匙 從入門到架構的全鏈路指南

💝💝💝歡迎蒞臨我的博客,很高興能夠在這里和您見面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內容和知識,也可以暢所欲言、分享您的想法和見解。 持續學習,不斷…

LabVIEW 與 PLC 通訊

在工業自動化領域,LabVIEW 與 PLC 的通訊極為關鍵,它能實現設備間高效的數據交互與協同運作。接下來,將從應用場景、軟件架構、功能實現、特點、開發問題及解決方法等層面展開闡述。 應用場景? 智能工廠生產線監控系統中,LabVIE…

11-FreeRTOS任務相關的其他API函數

數據來源地址:gitee.com FreeRTOS任務相關的其他API函數 一、FreeRTOS任務相關的其他API函數介紹 1、FreeRTOS任務相關API函數介紹(部分常用的) 答: 二、任務狀態查詢API函數 1、獲取任務優先級函數 答: UBaseType_t uxTaskPriorityGet…

ECMAScript(2)核心語法課件(Node.js/React 環境)

📚 ECMAScript 核心語法課件(Node.js/React 環境) 1. 變量與作用域 變量聲明方式 var:函數作用域,存在變量提升(hoisting)console.log(a); // undefined(變量提升) var a…