MySQL MVCC 機制詳解

MySQL MVCC 機制詳解

1. MVCC 基本概念

MVCC 是一種并發控制的方法,主要用于數據庫管理系統,允許多個事務同時讀取數據庫中的同一個數據項,而不需要加鎖,從而提高了數據庫的并發性能。

┌─────────────────────────────────────┐
│         MVCC 的核心思想              │
│                                     │
│  對數據進行修改操作時,不會直接覆蓋數據,│
│  而是創建一個新版本,讓讀操作可以看到   │
│  修改前的數據                        │
└─────────────────────────────────────┘

2. MVCC 在 InnoDB 中的實現

InnoDB 引擎下 MVCC 的實現主要基于以下幾個關鍵概念:

2.1 隱藏字段

InnoDB 為每一行記錄添加了三個隱藏字段:

┌───────────────────────────────────────────────────────┐
│                   InnoDB 行記錄結構                     │
├───────────┬───────────┬───────────┬───────────────────┤
│ DB_TRX_ID │ DB_ROLL_PTR│ DB_ROW_ID │ 實際數據列(可見部分) │
│ 事務ID    │ 回滾指針   │ 行ID(可選) │                    │
└───────────┴───────────┴───────────┴───────────────────┘
  • DB_TRX_ID:創建或最后修改該記錄的事務ID
  • DB_ROLL_PTR:指向 undo log 的指針,用于數據回滾
  • DB_ROW_ID:如果沒有主鍵,InnoDB 會自動生成的行ID

2.2 undo log 版本鏈

當一行記錄被修改時,InnoDB 會將舊版本的記錄寫入 undo log,并在當前記錄中通過回滾指針指向這個 undo log 記錄,形成一個版本鏈。

┌──────────────────────────────────────────────────────────────┐
│                       版本鏈示意圖                            │
│                                                              │
│  最新記錄                                                     │
│  ┌─────────┬─────────┬─────────┬───────────┐                 │
│  │TRX_ID=30│ROLL_PTR │ROW_ID   │name="張三" │                 │
│  └─────────┴─────────┴─────────┴───────────┘                 │
│      │                                                       │
│      ▼ 回滾指針指向                                           │
│  Undo Log 1                                                  │
│  ┌─────────┬─────────┬─────────┬───────────┐                 │
│  │TRX_ID=20│ROLL_PTR │ROW_ID   │name="李四" │                 │
│  └─────────┴─────────┴─────────┴───────────┘                 │
│      │                                                       │
│      ▼ 回滾指針指向                                           │
│  Undo Log 2                                                  │
│  ┌─────────┬─────────┬─────────┬───────────┐                 │
│  │TRX_ID=10│ROLL_PTR │ROW_ID   │name="王五" │                 │
│  └─────────┴─────────┴─────────┴───────────┘                 │
│                                                              │
└──────────────────────────────────────────────────────────────┘

2.3 ReadView

ReadView 是 MVCC 實現的關鍵機制,它決定了當前事務能夠看到哪個版本的數據。ReadView 包含以下重要信息:

  • m_ids:當前系統中活躍的事務ID集合
  • min_trx_id:活躍的最小事務ID
  • max_trx_id:系統中將要分配給下一個事務的ID
  • creator_trx_id:創建該 ReadView 的事務ID
┌──────────────────────────────────────────────┐
│               ReadView 示意圖                 │
│                                              │
│  ┌────────────────────────────────────────┐  │
│  │ m_ids: [10, 20, 30]                    │  │
│  │ min_trx_id: 10                         │  │
│  │ max_trx_id: 40                         │  │
│  │ creator_trx_id: 25                     │  │
│  └────────────────────────────────────────┘  │
│                                              │
└──────────────────────────────────────────────┘

3. MVCC 可見性判斷規則

當一個事務要讀取一行記錄時,它會根據 ReadView 和記錄的 DB_TRX_ID 來判斷該版本的記錄是否可見:

┌─────────────────────────────────────────────────────────────────┐
│                  MVCC 可見性判斷流程圖                           │
│                                                                 │
│   ┌───────────────┐                                             │
│   │ 開始判斷可見性 │                                             │
│   └───────┬───────┘                                             │
│           ▼                                                     │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id == creator_trx_id?    ├────────────?│ 可見     │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id < min_trx_id?         ├────────────?│ 可見     │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id >= max_trx_id?        ├────────────?│ 不可見   │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│   ┌───────────────────────────────┐     是     ┌───────────┐     │
│   │ trx_id 在 m_ids 中?           ├────────────?│ 不可見   │     │
│   └───────────┬───────────────────┘            └───────────┘     │
│               │ 否                                               │
│               ▼                                                 │
│               ┌───────────┐                                     │
│               │ 可見      │                                     │
│               └───────────┘                                     │
└─────────────────────────────────────────────────────────────────┘

4. 不同隔離級別下的 MVCC 行為

MVCC 主要在 READ COMMITTED 和 REPEATABLE READ 隔離級別下工作:

┌─────────────────────────────────────────────────────────────────┐
│               不同隔離級別的 ReadView 創建時機                    │
│                                                                 │
│  ┌────────────────────┐        ┌─────────────────────────────┐  │
│  │    READ COMMITTED  │        │      REPEATABLE READ       │  │
│  ├────────────────────┤        ├─────────────────────────────┤  │
│  │                    │        │                             │  │
│  │ 每次SELECT時創建新的 │        │ 事務開始時創建一次ReadView   │  │
│  │ ReadView           │        │ 之后所有查詢復用這個ReadView │  │
│  │                    │        │                             │  │
│  └────────────────────┘        └─────────────────────────────┘  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.1 READ COMMITTED

  • 每次SELECT都會創建一個新的ReadView
  • 可以看到其他已提交事務的更改
  • 解決了臟讀問題,但可能出現不可重復讀

4.2 REPEATABLE READ(MySQL默認)

  • 在事務開始時創建一個ReadView,之后的查詢都復用這個ReadView
  • 在整個事務過程中,對已經讀取的數據,其他事務的更新對當前事務不可見
  • 解決了不可重復讀問題

5. MVCC的實際例子

假設我們有一個簡單的表格和以下操作序列:

創建表: CREATE TABLE user(id INT PRIMARY KEY, name VARCHAR(20));
初始數據: INSERT INTO user VALUES(1, '小明');

接下來,有三個事務同時操作這條記錄:

┌─────────────────────────────────────────────────────────────────┐
│                       事務并發執行示例                            │
│                                                                 │
│  時間 │ 事務A(trx_id=10)  │ 事務B(trx_id=20)  │ 事務C(trx_id=30)  │
│ ─────┼──────────────────┼──────────────────┼────────────────── │
│  t1  │ BEGIN;           │                  │                   │
│  t2  │                  │ BEGIN;           │                   │
│  t3  │                  │                  │ BEGIN;            │
│  t4  │ SELECT * FROM    │                  │                   │
│      │ user WHERE id=1; │                  │                   │
│      │ 結果: '小明'      │                  │                   │
│  t5  │                  │ UPDATE user SET  │                   │
│      │                  │ name='小紅'       │                   │
│      │                  │ WHERE id=1;      │                   │
│  t6  │                  │ COMMIT;          │                   │
│  t7  │ SELECT * FROM    │                  │                   │
│      │ user WHERE id=1; │                  │                   │
│      │ 結果(RC): '小紅'  │                  │                   │
│      │ 結果(RR): '小明'  │                  │                   │
│  t8  │                  │                  │ UPDATE user SET   │
│      │                  │                  │ name='小黑'        │
│      │                  │                  │ WHERE id=1;       │
│  t9  │                  │                  │ COMMIT;           │
│ t10  │ SELECT * FROM    │                  │                   │
│      │ user WHERE id=1; │                  │                   │
│      │ 結果(RC): '小黑'  │                  │                   │
│      │ 結果(RR): '小明'  │                  │                   │
│ t11  │ COMMIT;          │                  │                   │
└─────────────────────────────────────────────────────────────────┘

版本鏈變化過程:

初始狀態:
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=1 │ROLL_PTR │ROW_ID   │name="小明" │
└─────────┴─────────┴─────────┴───────────┘事務B更新后:
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=20│ROLL_PTR │ROW_ID   │name="小紅" │
└─────────┴─────────┴─────────┴───────────┘│▼
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=1 │ROLL_PTR │ROW_ID   │name="小明" │
└─────────┴─────────┴─────────┴───────────┘事務C更新后:
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=30│ROLL_PTR │ROW_ID   │name="小黑" │
└─────────┴─────────┴─────────┴───────────┘│▼
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=20│ROLL_PTR │ROW_ID   │name="小紅" │
└─────────┴─────────┴─────────┴───────────┘│▼
┌─────────┬─────────┬─────────┬───────────┐
│TRX_ID=1 │ROLL_PTR │ROW_ID   │name="小明" │
└─────────┴─────────┴─────────┴───────────┘

6. MVCC的優缺點

優點:

  • 提高并發性能,讀不阻塞寫,寫不阻塞讀
  • 解決了讀-寫沖突問題
  • 支持事務的隔離級別實現

缺點:

  • 需要額外的存儲空間維護舊版本數據
  • 需要定期清理過時的舊版本數據
  • 實現較為復雜

總結

MVCC 是 MySQL InnoDB 存儲引擎中實現高并發的關鍵技術,通過在每行記錄后面保存兩個隱藏的列(事務ID和回滾指針)來實現的。它能夠讓不同事務的讀、寫操作并發執行,同時保證事務的隔離性。根據不同的隔離級別,MySQL 會采用不同的策略來創建和維護 ReadView,從而影響數據的可見性。

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

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

相關文章

Model Context Protocol (MCP) - 嘗試創建和測試一下MCP Server

1.簡單介紹 MCP是Model Context Protocol的縮寫&#xff0c;是Anthropic開源的一個標準協議。MCP使得大語言模型可以和外部的數據源&#xff0c;工具進行集成。當前MCP在社區逐漸地流行起來了。同時official C# SDK(倉庫是csharp-sdk) 也在不斷更新中&#xff0c;目前最新版本…

(三)行為模式:12、訪問者模式(Visitor Pattern)(C++示例)

目錄 1、訪問者模式含義 2、訪問者模式的UML圖學習 3、訪問者模式的應用場景 4、訪問者模式的優缺點 5、訪問者模式C實現的實例 1、訪問者模式含義 訪問者模式&#xff08;Visitor Pattern&#xff09;是一種行為型設計模式&#xff0c;它允許將一個作用于某對象結構中的各…

windows安卓子系統wsa隱藏應用列表的安裝激活使用

Windows 11 安卓子系統應用部署全攻略 windows安卓子系統wsa隱藏應用列表的安裝激活使用|過檢測核心前端 在 Windows 11 系統中&#xff0c;安卓子系統為用戶帶來了在電腦上運行安卓應用的便利。經過一系列的操作&#xff0c;我們已經完成了 Windows 11 安卓子系統的底層和前端…

Elasticsearch 集群搭建

一、集群規劃 1.1 節點角色規劃 節點類型配置要求推薦數量Master節點低磁盤、中等CPU/內存3&#xff08;奇數防止腦裂&#xff09;Data節點高磁盤、高內存、多核CPU根據數據量擴展Coordinating節點高CPU/內存、低磁盤2&#xff08;可選&#xff09; 1.2 硬件建議 內存&…

React 響應事件

開發環境&#xff1a;Reacttsantd 使用 React 可以在 JSX 中添加 事件處理函數。其中事件處理函數為自定義函數&#xff0c;它將在響應交互&#xff08;如點擊、懸停、表單輸入框獲得焦點等&#xff09;時觸發。 學習內容 1.編寫事件處理函數的不同方法 2.如何從父組件傳遞事件…

SQL基礎入門:從CRUD到JOIN再到索引(通俗易懂版)

一、為什么需要SQL&#xff1f; 想象你在管理一個圖書館&#xff1a; 傳統方法&#xff1a;手動記錄每本書的位置、借閱者、歸還日期SQL方法&#xff1a;用數據庫系統自動管理&#xff0c;快速查詢《Java編程思想》在哪個書架 SQL&#xff08;Structured Query Language&…

MINIQMT學習課程Day11

現在開始進行策略的交易買賣分析&#xff1a; 還是之前的步驟&#xff0c;打開qmt&#xff0c;選擇獨立交易&#xff0c; 之后使用pycharm&#xff0c;編寫py文件 導入包&#xff1a; import time, datetime, traceback, sys from xtquant import xtdata from xtquant.xttr…

# 實時人臉性別與年齡識別:基于OpenCV與深度學習模型的實現

實時人臉性別與年齡識別&#xff1a;基于OpenCV與深度學習模型的實現 在當今數字化時代&#xff0c;計算機視覺技術正以前所未有的速度改變著我們的生活與工作方式。其中&#xff0c;人臉檢測與分析作為計算機視覺領域的重要分支&#xff0c;已廣泛應用于安防監控、智能交互、…

Python Cookbook-5.14 給字典類型增加排名功能

任務 你需要用字典存儲一些鍵和“分數”的映射關系。你經常需要以自然順序(即以分數的升序)訪問鍵和分數值&#xff0c;并能夠根據那個順序檢查一個鍵的排名。對這個問題&#xff0c;用dict 似乎不太合適。 解決方案 我們可以使用 dict 的子類&#xff0c;根據需要增加或者重…

十四種邏輯器件綜合對比——《器件手冊--邏輯器件》

目錄 邏輯器件 簡述 按功能分類 按工藝分類 按電平分類 特殊功能邏輯器件 應用領域 詳盡闡述 1 邏輯門 一、基本概念 二、主要類型 三、實現方式 四、應用領域 2 反相器 工作原理 基本功能 主要應用 常見類型 特點 未來發展趨勢 3 鎖存器 基本概念 工作原理 主要類型…

如何更改wsl2中的ubuntu默認安裝位置

先前的一篇文章提到了如何更改wsl里面ubuntu的home目錄&#xff0c;wsl裝ubuntu的home目錄在哪&#xff0c;如何更改home&#xff1f;_wsl安裝的ubuntu在哪里-CSDN博客 這次是要更改wsl中ubuntu的安裝目錄&#xff0c;畢竟默認安裝到c盤下會占用不少空間的。 從微軟商店get后…

最近在工作中感受到了設計模式的重要性

之前了解設計模式&#xff1a;只是應付一下面試 在之前一年多的工作中也沒遇到使用場景 最近在搭建驗證環境的時候&#xff0c;才發現這玩意這么重要 首先是設計模式的使用場景一定是在很復雜繁瑣的場景下進行的 之所以說是復雜/繁瑣的場景&#xff0c;因為一些場景也許邏輯不難…

Python深度學習基礎——卷積神經網絡(CNN)(PyTorch)

CNN原理 從DNN到CNN 卷積層與匯聚 深度神經網絡DNN中&#xff0c;相鄰層的所有神經元之間都有連接&#xff0c;這叫全連接&#xff1b;卷積神經網絡 CNN 中&#xff0c;新增了卷積層&#xff08;Convolution&#xff09;與匯聚&#xff08;Pooling&#xff09;。DNN 的全連接…

Linux 第三講 --- 基礎指令(三)

前言&#xff1a; 在前面我們已經講了有十幾個Linux的基礎指令&#xff0c;今天我們再補充幾個常用的基礎指令&#xff0c;為后面的學習做準備 。 目錄 前言&#xff1a; 一、兩個與時間相關的指令 1.date指令 演示 &#xff1a; 時間戳 設置時間 2、cal指令 演示&#x…

基于SiamFC的紅外目標跟蹤

基于SiamFC的紅外目標跟蹤 1,背景與原理2,SiamFC跟蹤方法概述2.1 核心思想2.2 算法優勢3,基于SiamFC的紅外跟蹤代碼詳解3.1 網絡定義與交叉相關模塊3.2 SiamFC 跟蹤器實現3.3 主程序:利用 OpenCV 實現視頻跟蹤4,總結與展望在紅外監控、無人機防御以及低光照場景中,紅外圖…

Odoo 部署本地 把現時的excel計算表格部署上odoo 教程

要將現有的 Excel 計算表格部署到 Odoo 平臺上&#xff0c;您可以按照以下步驟進行操作&#xff1a; 將 Excel 表格中的數據轉移到 Odoo 模塊中&#xff1a;首先&#xff0c;您需要將 Excel 表格中的數據導出為 CSV 格式&#xff0c;然后可以使用 Odoo 的數據導入功能將這些數據…

KWDB創作者計劃—KWDB認知引擎:數據流動架構與時空感知計算的范式突破

引言&#xff1a;數據智能的第三范式 在數字化轉型進入深水區的2025年&#xff0c;企業數據系統正面臨三重悖論&#xff1a;數據規模指數級增長與實時決策需求之間的矛盾、多模態數據孤島與業務連續性要求之間的沖突、靜態存儲范式與動態場景適配之間的鴻溝。KWDB&#xff08;K…

C語言 數據結構 【棧】動態模擬實現

引言 動態模擬實現棧的各個接口 一、棧的概念與結構 棧&#xff1a;一種特殊的線性表&#xff0c;其只允許在固定的一端進行插入和刪除元素操作。進行數據插入和刪除操作的一端稱為棧頂&#xff0c;另一端稱為棧底。棧中的數據元素遵守后進先出LIFO&#xff08;LastInFirstOut…

Python itertools模塊的groupby函數介紹

itertools.groupby 是 Python 標準庫 itertools 模塊中的一個函數&#xff0c;它的主要功能是對可迭代對象中相鄰的相同元素進行分組。 itertools.groupby(iterable, keyNone) 函數 作用&#xff1a; 將連續的&#xff08;相鄰的&#xff09;相同元素分組&#xff0c;返回 (…

Python實例題:使用Python生成分形圖片

目錄 Python實例題 題目 題目分析 需求理解 關鍵知識點 實現思路分析 代碼實現 代碼解釋 mandelbrot 函數&#xff1a; 設置復平面區域和圖像參數&#xff1a; 計算分形數據&#xff1a; 繪圖展示&#xff1a; 運行思路 Python實例題 題目 使用Python生成分形圖…