MySQL——MVCC

1.為什么需要MVCC

在并發場景下,讀寫操作會面臨嚴重的沖突問題:

1.讀操作如果遇到寫操作,要么“讀到未提交的臟數據”,要么“被寫操作阻塞(等待鎖釋放)”;

2.寫操作如果遇到讀操作,要么“覆蓋讀操作需要的數據”,要么“被讀操作阻塞”;

MVCC通過“多版本”解決了這個問題:寫操作會生成新的數據版本,讀操作讀取舊的版本(不影響寫),兩者不干擾。

2.什么是MVCC

MySQL的MVCC(Multi-Version Concurrency Control,多版本并發控制)是InnoDB存儲引擎實現高并發讀寫的核心操作。核心思想:為數據庫中的每條記錄維護多個版本,通過“版本鏈”和“可間性判斷規則”,讓不同實物在并發訪問時,能夠看到符合自己隔離級別的數據版本,從而避免讀寫沖突(讀不阻塞寫,寫不阻塞讀),同事保證事務隔離性。

3.MVCC的核心組成

MVCC的實現依賴三個關鍵組件:隱藏列(版本標識)Undo Log(版本存儲)Read View(可見性判斷)

3.1 隱藏列:記錄的“版本身份證”

InnoDB為表中的每條記錄添加了三個隱藏字段,用于記錄標識的版本信息

  • DB_TRX_ID:記錄最后一次修改該記錄的事務ID(6字節)。每次事務對記錄執行insert/update/delete時,都會將自己的事務ID寫入該字段。
  • DB_ROLL_PTR:回滾指針(7字節)。指向該記錄的“上個版本”在Undo Log中的位置(通過它可以串聯所有的歷史版本,形成“版本鏈”)。
  • DB_ROW_ID:記錄的唯一標識(6字節)。如果表沒有定義主鍵或唯一索引,InnoDB會用它作為默認聚簇索引(一般用不到,可忽略)。

3.2 Undo Log:版本的“歷史記錄館”

Undo Log(回滾日志)是InnoDB用于存儲“記錄舊版本”的空間。當視為修改記錄時,舊版本的數據不會被直接刪除,而是被寫入Undo Log,供后序“回滾”或“其他事務讀取”使用。

與隱藏列相結合形成“版本鏈”,記錄的“版本鏈”形成的過程如下:

  1. 初始插入一條數據時,DB_TRX_ID是插入事務的ID,DB_ROLL_PTR為null(無歷史版本,新數據無歷史版本)。
  2. 當事務A(事務ID=110)修改該記錄時,InnoDB會先將舊版本數據寫入Undo Log,然后更新記錄的DB_TRX_ID=110,并將DB_ROLL_PTR指向Undo Log中的舊版本。
  3. 之后事務B(事務ID=220)再次修改該記錄時,會將“事務A修改后的版本”寫入Undo Log,更新DB_TRX_ID=220,DB_ROLL_PTR指向事務A版本再Undo Log的位置。
  4. 最終,通過DB_ROLL_PTR串聯的Undo Log記錄,形成了改記錄的“版本鏈”(最新版本在表中,歷史版本在Undo Log中)。

一條記錄的版本鏈結構(簡化):
當前記錄(表中):

data:(name='HajiHang',age=21)|DB_TRX_ID=220|DB_ROLL_PTR——>Undo Log中的版本1

Undo Log:

Undo Log中的版本1(事務A修改后的版本):

data:(name='HajiHang',age=20)|DB_TRX_ID=110|DB_ROLL_PTR——>Undo Log中的版本0

Undo Log中的版本0(初始插入版本):

data:(name='HajiHang',age=19)|DB_TRX_ID=55|DB_ROLL_PTR——>null

3.3 Read View:版本的“可見性過濾器”

有了版本鏈后,事務如何判斷“哪個版本的數據對自己可見”?這就需要Read View(讀試圖),它是一個“可見性判斷規則集合”,用于確定當前事務能夠看到版本鏈中的那個版本。

Read View包含4個核心變量(生成時確定):

  1. m_ids:生成Read View時,當前所有“活躍事務”(已啟動但未提交)的事務ID集合(無序)
  2. min_trx_id:m_ids中的最小事務ID(當前活躍事務中最早啟動的那個)
  3. max_trx_id:生成Read View時,“下一個將要分配的事務ID”(并非m_ids中的最大值,而是一個預分配的自增ID)
  4. creator_trx_id:當前生成Read View的事務自己的ID

4.可見性判斷規則(核心)

設記錄的版本對應的事務ID為trx_id,根據trx_id和Read View的變量對比:

  • 如果trx_id == creator_trx_id:該版本是當前事務自己修改的,可見(自己改的自己當然可以看到)
  • 如果trx_id < min_trx_id:該版本對應的事務在“當前Read View生成前”就已提交(因為它的ID比所有活躍事務的最小ID還小),可見。
  • 如果trx_id >= max_trx_id:該版本對應的事務在“當前Read View生成后”才啟動(ID超過預分配的最大ID),不可見(還沒提交,或剛啟動)。
  • 如果min_trx_id <=trx_id <=max_trx_id:
    • 若trx_id在m_ids(活躍事務集合)中:說明該事務在Read View生成時還沒提交,不可見;
    • 若trx_id不在m_ids中:說明該事務在Read View生成前已提交,可見;

5.MVCC與隔離級別的關系

MVCC的核心作用是實現隔離級別(ACID中的“I”隔離性)。InnoDB通過“Read View的生成時機”和“版本鏈”,在不同隔離級別下表現出不同的行為:

隔離級別MVCC行為(Read View生成時機)解決的問題
Read Uncommitted(讀未提交)不使用MVCC(直接讀取最新的版本)可能讀到未提交的臟數據(臟讀)
Read Committed(讀已提交)每次執行select時,重新生成Read View避免臟讀(只看到已提交的版本);但是可能出現“不可重復讀”(兩次查詢Read View不同)
Repeatable Read(可重復讀)僅在事務第一次select生成Read View,之后復用避免不可重復讀(兩次查詢用同一個Read View,版本一致);但可能出現“幻讀”(通過間隙鎖解決)
Serializable(串行化)不依賴MVCC,直接通過加鎖(讀加共享鎖,寫加排它鎖)實現完全串行化,無并發問題,性能低

6.補充:不同隔離級別涉及到的并發問題

不同隔離級別會產生不同的并發問題,核心問題包括臟讀,不可重復讀,幻讀。

  • 臟讀指的是一個事務讀取到另一個為提交事務修改的數據。(事務A在修改name并未提交,事務B讀取到了name,后事務A又進行修改并提交/或直接回滾,導入事務B讀取到了一個臨時,無效的數據)
  • 不可重復讀指的是同一事務內,多次讀取同一數據,結果因其他已提交事務的修改而不同。(事務A第一次讀取name='HajiHang',事務B執行了修改操作將name改成了Hajimi,事務A再次讀取name發現不是HajiHang了)
  • 幻讀指的是同一事務內,多次執行相同的查詢操作(通常是范圍查詢)時,結果集行數因其他一提交事務的插入/刪除而變化(事務A查詢score=90的人發現有5條數據,之后事務B插入一個90的數據,事務A再次查詢score=90發現結果集變為6條)

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

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

相關文章

數據結構第2問:什么是算法?

算法 算法是一組用于解決具體問題的、明確的、有序的步驟或規則&#xff0c;能夠在有限的時間內通過這些步驟得到問題的答案。 算法的5個重要特性&#xff1a; 有窮性&#xff1a;算法必須在有限的步驟內結束&#xff0c;不能無限循環&#xff0c;保證最終能夠得到結果。確定性…

12-大語言模型—Transformer 打地基,下游任務蓋出百樣房,指標來驗收|下游任務白話指南

目錄 1、核心邏輯&#xff1a;Transformer 的 “語言處理閉環” 2、轉導與感知 → 模型咋 “理解語言”&#xff1f; 2.1、 人類 vs 機器的 “語言理解邏輯” 2.2、 自注意力機制&#xff1a;模型 “理解語言” 的數學核心 2.2.1、通俗拆解 2.2.1.1、是什么&#xff1f; …

深入探索爬蟲與自動化腳本:釋放效率的利器

在當今信息爆炸的時代&#xff0c;高效獲取和處理數據已成為核心競爭力。爬蟲與自動化腳本正是解決這一痛點的關鍵技術——它們如同數字世界的勤勞助手&#xff0c;幫我們自動完成繁瑣重復的任務。下面我們來系統了解這兩項技術的核心要點、應用場景和最佳實踐。一、爬蟲與自動…

React函數組件的“生活管家“——useEffect Hook詳解

&#x1f3af; React函數組件的"生活管家"——useEffect Hook詳解 1. &#x1f31f; 開篇&#xff1a;從生活中的"副作用"說起 嘿&#xff0c;各位掘友們&#xff01;今天咱們來聊聊React函數組件里的一個“大管家”——useEffect Hook。你可能會問&#x…

python基礎:request請求Cookie保持登錄狀態、重定向與歷史請求、SSL證書校驗、超時和重試失敗、自動生成request請求代碼和案例實踐

Cookie保持登錄狀態cookie session鑒權機制 cookie是由web服務器保存在用戶瀏覽器&#xff08;客戶端&#xff09;上的小文本文件&#xff0c;他可以包含有關用戶的信息。無論何時用戶訪問到服務器&#xff0c;都會帶上該服務器的cookie信息&#xff0c;一般cookie都是有有效期…

Vulkan入門教程 | 第二部分:創建實例

前言&#xff1a;本教程為筆者依據教程https://docs.vulkan.net.cn/spec/latest/index.html#_about進行Vulkan學習并結合自己的理解整理的筆記&#xff0c;供大家學習和參考。 &#xff08;注意&#xff1a;代碼僅為片段&#xff0c;非完整程序&#xff09; 學習前提&#xff1…

PHP云原生架構:容器化、Kubernetes與Serverless實踐

引言 隨著云計算的普及,PHP應用也在向云原生架構演進。本文將深入探討PHP在云原生環境中的最佳實踐,包括容器化部署、Kubernetes編排、Serverless架構以及云原生監控與日志方案,幫助開發者構建現代化、可擴展的PHP應用。 容器化PHP應用 基礎Dockerfile優化 # 多階段構建…

【華為機試】5. 最長回文子串

文章目錄5. 最長回文子串描述示例 1示例 2示例 3示例 4提示解題思路方法一&#xff1a;中心擴展法&#xff08;推薦&#xff09;方法二&#xff1a;動態規劃方法三&#xff1a;Manacher算法方法四&#xff1a;暴力解法代碼實現復雜度分析測試用例完整題解代碼5. 最長回文子串 …

【圖像處理基石】如何對遙感圖像進行實例分割?

遙感圖像實例分割是指在遙感影像中&#xff0c;不僅要識別出不同類別的目標&#xff08;如建筑物、車輛、道路等&#xff09;&#xff0c;還要區分同一類別中的不同個體&#xff08;如建筑物1、建筑物2&#xff09;&#xff0c;并為每個實例生成精確的像素級掩碼。 一、遙感圖…

電子電氣架構 --- 軟件bug的管理模式

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

【每日一錯】Oracle 19c CDB中如何啟動一個PDB

文章目錄題目擴展學習CDB與PDB的概念CDB&#xff0c;PDB結構優勢總結題目 擴展學習 CDB與PDB的概念 在Oracle 12c及以上版本&#xff0c;Oracle引入了多租戶架構&#xff0c;這種架構讓數據庫的管理和資源使用更加高效。它由兩種主要組成部分組成&#xff1a; CDB&#xff0…

Android studio自帶的Android模擬器都是x86架構的嗎,需要把arm架構的app翻譯成x86指令?

Android studio自帶的Android模擬器都是x86架構的嗎&#xff0c;需要把arm架構的app翻譯成x86指令&#xff1f; deepseek回答&#xff1a; Android Studio 自帶的官方模擬器&#xff08;Android Emulator&#xff09;主要提供基于 x86 架構的系統鏡像。當運行 ARM 架構的應用…

Deep Learning_ Foundations and Concepts-Springer (2024)【拜讀】20章3節

Diffusion Models 擴散模型 我們已經了解到&#xff0c;構建強大的生成模型的一種有效方法是&#xff1a;先引入一個關于潛在變量z的分布p(z)&#xff0c;然后使用深度神經網絡將z變換到數據空間x。由于神經網絡具有通用性&#xff0c;能夠將簡單固定的分布轉化為關于x的高度靈…

Arduino與STM32:初學者該如何選擇?

在電子愛好者和初學者的世界里&#xff0c;Arduino和STM32是兩個經常被提及的名字。它們各自具有獨特的優勢和特點&#xff0c;適合不同類型的項目和需求。對于初學者來說&#xff0c;選擇Arduino還是STM32&#xff0c;往往取決于個人的學習目標、項目需求以及預算。本文將詳細…

創建型設計模式-工廠方法模式和抽象工廠方法模式

1、工廠方法模式 創建型設計模式之一 UML類圖2、抽象工廠模式 也是創建型設計模式之一。雖然抽象工廠方法模式的類繁多&#xff0c;但是&#xff0c;主要分為4類。 AbstractFactory&#xff1a;抽象工廠角色&#xff0c;它聲明了一組用于創建一種產品的方法&#xff0c;每一個方…

Hyperchain安全與隱私機制詳解

一、核心安全機制1. 共識算法安全RBFT共識算法&#xff1a;改進型PBFT&#xff1a;基于PBFT算法優化&#xff0c;增加動態節點管理、失效數據恢復機制&#xff0c;提升系統容錯性與可用性。性能指標&#xff1a;吞吐量穩定達3000-10000 TPS&#xff0c;交易執行時間控制在300ms…

Oracle優化學習十六

反連接反連接&#xff08;Anti Join&#xff09;是一種特殊的連接類型&#xff0c;與內連接和外連接不同&#xff0c;Oracle數據庫里并沒有相關的 關鍵字可以在SQL文本中專門表示反連接&#xff0c;所以這里把它單獨拿出來說明。為了方便說明反連接的含義&#xff0c;我們用“t…

梳理一些 Docker 常用命令

以下是一些 Docker 常用命令&#xff0c;適用于日常開發、調試、部署等場景&#xff0c;分為幾個常用類別&#xff1a;&#x1f4e6; 一、鏡像&#xff08;Image&#xff09;相關命令命令說明docker images查看本地所有鏡像docker pull <image>拉取鏡像&#xff08;如 do…

C#_ArrayList動態數組

目錄 ArrayList的特點 ArrayList 與普通數組的區別 使用示例&#xff1a; 普通數組 動態數組 主要方法和屬性 屬性&#xff1a; Count 獲取動態數組的數據個數 讀取某個位置的數據 // 索引 方法&#xff1a; Add 向集合末尾添加元素 Insert 在指定位置插入元…

Agent領域,近年來的前沿研究方向:多智能體協作、認知啟發架構、倫理安全、邊緣計算集成

Agent領域,近年來的前沿研究方向:多智能體協作、認知啟發架構、倫理安全、邊緣計算集成 在Agent領域,近年來的前沿研究方向主要集中在多智能體協作、認知啟發架構、倫理安全、邊緣計算集成以及生成式AI融合等方面。 一、多智能體協作與多模態任務 多智能體系統在復雜環境…