MYSQL數據庫(九)MVCC-多版本并發控制

目錄

一 前景導入

1 當前讀

2 快照讀

二 MVCC

1 隱藏字段

2 UndoLog 回滾日志

(1 UndoLog日志

(2 UndoLog版本鏈

3 Read?View

面試八股

?介紹一下MVCC


一 前景導入

1 當前讀

可使當前事務讀取的是最新版本的數據,讀取時還要保證其他并發事務不能修改當中記錄,會對讀取的記錄進行加鎖。

  • SELECT ... LOCK IN SHARE MODE?(共享鎖/S鎖)

  • SELECT ... FOR UPDATE?(排他鎖/X鎖)

  • UPDATEINSERTDELETE?操作(自動加排他鎖)

2 快照讀

簡單的select(不加鎖)就是快照讀,讀取的是記錄數據的可見版本,有可能是歷史數據,不加鎖。

快照讀本質上就是使用MVCC機制訪問數據的歷史版本

隔離級別快照讀行為當前讀行為
Read Committed每次 SELECT 都生成新的快照(能看到其他事務已提交的修改)始終讀取最新已提交版本并加鎖
Repeatable Read事務中第一個 SELECT 語句建立快照,后續讀取都基于此快照(看不到后續修改)始終讀取最新已提交版本并加鎖
Serializable快照讀退化為當前讀(所有 SELECT 自動轉為 SELECT ... LOCK IN SHARE MODE)正常當前讀行為

二 MVCC

概念:MVCC全稱:多版本并發控制。

MVCC允許多個事務同時讀取同一行數據,但是確保了數據版本是當前事務開啟之前的版本。(其他事務修改但是看見的版本還是修改之前的)

1 隱藏字段

在 InnoDB 的 MVCC 實現中,每條記錄都包含三個關鍵隱藏字段,它們共同構建了多版本控制的基石:

字段名大小作用是否必選
DB_TRX_ID?事務ID6 字節記錄最后修改該行的事務 ID?總是存在
DB_ROLL_PTR?回滾指針7 字節指向 Undo Log 中上一個版本的指針(構成版本鏈)?總是存在
DB_ROW_ID6 字節隱式自增主鍵(僅當無主鍵時生成)?條件存在

2 UndoLog 回滾日志

(1 UndoLog日志

概念:回滾日志,用于記錄數據被修改前的信息

作用:是數據庫實現事務原子性和多版本并發控制的核心機制

場景化描述
當事務需要回滾或一致性讀時,內存中可能存在未提交的修改。
重啟后或事務內,Undo Log 能提供舊數據版本,用于:

  • 撤銷未提交的操作(回滾)

  • 構造歷史快照(MVCC 非阻塞讀)

(2 UndoLog版本鏈

Undo Log 版本鏈的核心價值正是通過精準的指針定位實現對歷史版本的精確訪問。

3 Read?View

讀視圖,用于決定事務能看到哪些版本的數據。本質上是事務啟動時對數據庫系統狀態的一次快照,解決了并發讀寫當中的數據可見性問題。

Read View 包含四個關鍵字段:

字段名描述作用
m_ids生成 Read View 時活躍事務ID列表(未提交的事務)判斷數據版本是否由未提交事務創建
min_trx_id活躍事務中的最小事務ID加速判斷:事務ID < min_trx_id 一定可見
max_trx_id系統預分配的下一個事務ID(非當前最大ID)判斷:事務ID ≥ max_trx_id 一定不可見
creator_trx_id創建該 Read View 的事務ID(當前事務自身ID)避免看到自己未提交的修改

讀已提交這個隔離級別當中,在每一個select 語句執行前都會生成一個ReadView。導致出現不可重復讀的現象,可能出現兩次讀取數據不同的情況。

可重復讀是執行第一條select時,生成一個ReadView然后整個業務期間都在使用這個ReadView。讀取的數據始終相同,無視其他事務的提交。

舉個例子

-- 事務A (RC級別)
BEGIN;  -- trx_id=100 (事務A被分配ID=100)-- 第一次查詢 (創建ReadView1)
SELECT balance FROM accounts WHERE id=1; -- 返回1000
/* 
ReadView1狀態:m_ids = [100]          -- 活躍事務ID列表 (當前只有事務A)min_trx_id = 100       -- 最小活躍事務ID (m_ids中的最小值)max_trx_id = 101       -- 下一個將分配的事務ID (當前最大事務ID+1)creator_trx_id = 100   -- 創建此ReadView的事務ID可見性判斷過程:假設數據行初始db_trx_id=90 (小于min_trx_id)90 < min_trx_id(100) → 可見 → 返回1000
*/-- 事務B (trx_id=101) 啟動并提交UPDATE accounts SET balance=900 WHERE id=1;-- 修改后數據行:--   db_trx_id = 101 (最后修改事務ID)--   db_roll_ptr → 指向舊版本(trx_id=90, balance=1000)COMMIT; -- 事務B提交,從活躍事務列表移除-- 第二次查詢 (創建新ReadView2)
SELECT balance FROM accounts WHERE id=1; -- 返回900
/* 
ReadView2狀態:m_ids = [100]          -- 活躍事務ID列表 (事務B已提交,只剩事務A)min_trx_id = 100       -- 最小活躍事務ID (仍是100)max_trx_id = 102       -- 下一個將分配的事務ID (101已使用)creator_trx_id = 100   -- 創建者事務ID可見性判斷過程:當前行db_trx_id=1011. 101 != creator_trx_id(100) → 非當前事務修改2. 101 >= min_trx_id(100) 且 101 < max_trx_id(102) → 在[mins, max)范圍內3. 檢查m_ids=[100] → 101不在其中 → 已提交 → 可見返回當前版本數據900
*/

可見性判斷規則優先級:

  • 首先檢查:db_trx_id == creator_trx_id(當前事務自身修改)

  • 然后檢查:db_trx_id < min_trx_id(在ReadView創建前已提交)

  • 再檢查:db_trx_id >= max_trx_id(在ReadView創建后啟動的事務)讀取快照之后有事務過來修改了但是快照讀取的是那一瞬間的值故才會出現大于max預分配的情況

  • 最后檢查范圍:min_trx_id <= db_trx_id < max_trx_id

    • 在m_ids中 → 未提交 → 不可見

    • 不在m_ids中 → 已提交 → 可見

三 面試八股

?介紹一下MVCC

首先我想介紹的是MVCC是什么,MVCC全稱多版本并發控制,核心思想如同字面意思,為數據維護多個版本,而并非直接覆蓋。

其次再說說其功能,其主要解決的是讀寫之間沖突而導致的并發性能問題。他讓不同的事務在不同的隔離級別能看見不同的隔離級別,主要是RC與RR這兩種隔離級別(RC是在每一次讀取之前都會生成一個ReadView快照,而RR是只在第一次讀取之前生成一個ReadView快照,RR則在一次事務當中就不會出現不可重復讀的情況,而RC則會出現不可重復讀的現象(因為其允許其他事務對其進行寫的操作,導致讀取的數據可能會出現不同,呆滯出現不可重復讀))

核心:版本鏈+ReadView+undolog

這里說到了ReadView就涉及其原理部分了,這里就不得不提到一個隱藏字段,存儲在數據行當中的db_trx_id(最后修改數據的事務id),在讀取時會拿這個事務id與ReadView當中的字段進行對比,四個字段(創建當前ReadView事務的id,生成ReadView時活躍的最小事務id,生成ReadView時活躍的事務id的列表,生成ReadView時預分配的下一個事務id)

  • 首先檢查:db_trx_id == creator_trx_id(當前事務自身修改)可見

  • 然后檢查:db_trx_id < min_trx_id(在ReadView創建前已提交)可見

  • 再檢查:db_trx_id >= max_trx_id(在ReadView創建后啟動的事務)不可見

  • 最后檢查范圍:min_trx_id <= db_trx_id < max_trx_id

    • 在m_ids中 → 未提交 → 不可見

    • 不在m_ids中 → 已提交 → 可見

以上是對事務版本的判斷,判斷結束后如果是可見的,那么就直接返回該版本的數據作為查詢結果,但是如果不可見,那么就需要用到版本鏈回溯到之前的版本,獲取行數據的db_roll_ptr(回滾指針),指針指向上一個版本在undolog(回滾日志)當中具體位置

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

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

相關文章

[Pytest] [Part 2]增加 log功能

開始實現需求之前先做個log類&#xff0c;可以給其他模塊使用&#xff0c;也方便以后修改log類的功能和屬性。 使用的是python中的logging包來進行簡單的封裝&#xff0c;具體代碼如下 import logging import sysclass TefLogger:def __init__(self, logger_nameTEST_FRAMEWOR…

NeighborGeo:基于鄰居的IP地理定位(三)

NeighborGeo:基于neighbors的IP地理定位 X. Wang, D. Zhao, X. Liu, Z. Zhang, T. Zhao, NeighborGeo: IP geolocation based on neighbors, Comput. Netw. 257 (2025) 110896, 3. NeighborGeo 本文提出NeighborGeo,利用圖結構學習和有監督對比學習來建立可靠的地標-目標關…

python使用fastmcp包編寫mcp服務端(mcp_server)和mcp客戶端(mcp_client)

安裝fastmcp pip install fastmcp編寫mcp服務端代碼 from fastmcp import FastMCP mcp FastMCP(weather)mcp.tool() def get_weather(city: str):獲取對應城市的天氣:param city: 目標城市:return: 該城市的天氣return f"{city}天氣晴朗&#xff0c;溫度60度&#xff01…

(1)機器學習小白入門 YOLOv:從概念到實踐

(1)機器學習小白入門YOLOv &#xff1a;從概念到實踐 (2)機器學習小白入門 YOLOv&#xff1a;從模塊優化到工程部署 (3)機器學習小白入門 YOLOv&#xff1a; 解鎖圖片分類新技能 目標檢測一直是一個機器學習的一個重要的應用方向。而 YOLOv&#xff08;You Only Look Once&…

Appium 簡介

Appium 是一個開源的移動應用自動化測試框架&#xff0c;用于測試原生應用(native)、混合應用(hybrid)和移動網頁應用(mobile web)。它支持 iOS、Android 和 Windows 平臺。 https://www.bilibili.com/video/BV1R93szkEhi/? App自動化測試&#xff1a;App測試AppiumUiAutomato…

【C語言刷題】第十一天:加量加餐繼續,代碼題訓練,融會貫通IO模式

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題 &#x1f349;學習方向&#xff1a;C/C方向 ??人生格言&#xff1a;為天地立心&#xff0c;為生民立命&#xff0c;為…

免費版安全性縮水?ToDesk、TeamViewer、向日葵、網易UU遠程訪問隱私防護測評

一、前言 在這個居家辦公、遠程技術支持成為常態的時代&#xff0c;我們經常需要把電腦控制權交給遠方的同事或技術人員。但你想過沒有&#xff0c;那些免費遠程控制軟件&#xff0c;真的能保護好你的隱私嗎&#xff1f; 好用的遠程軟件通常會收費運營&#xff0c;投入經費去開…

nginx部署發布Vite項目

1 引言 在之前的文章《Ubuntu云服務器上部署發布Vite項目》中筆者使用了Vite提供的預覽服務(npm run preview)來在云服務器上發布Web應用。這樣做輕量應用是沒問題的&#xff0c;不過遇到一些專業的問題就不行了&#xff0c;最好還是使用專業的HTTP服務器。除此之外&#xff0…

Unity文件夾標簽 —— FolderTag

GitHub地址 FolderTag 下載之后解壓&#xff0c;將FolderTag文件夾拖進Unity項目的Assets文件夾 選中文件夾&#xff0c;填上標簽

【0基礎開發油猴腳本】某漫畫網站圖片旋轉

有朋友在用某漫畫網站在線看漫畫&#xff0c;但是那個網站會把漫畫圖片右旋90度&#xff0c;如圖。于是&#xff0c;他就像我發起了求助&#xff0c;問我能不能寫個腳本。我說&#xff0c;AI都發展到2025了&#xff0c;前端&#xff08;腳本&#xff09;這種東西還用自己寫嗎&a…

Vue Router 中,params參數的名稱必須與路由配置中的動態路徑參數名完全一致

路由配置與 params 參數的綁定關系 在路由配置中&#xff0c;使用 冒號&#xff08;:&#xff09; 定義動態路徑參數&#xff1a; // router.js&#xff08;路由配置&#xff09; { path: /search/:keyword, // 這里的:keyword是動態路徑參數 name: Search, component: S…

Spring Boot 應用開發實戰指南:從入門到實戰(內含實用技巧+項目案例)

&#x1f4d8; Spring Boot 應用開發實戰指南&#xff1a;從入門到實戰&#xff08;內含實用技巧項目案例&#xff09;&#x1f680; 你是否還在為 Spring 配置復雜、開發效率低下而苦惱&#xff1f;Spring Boot 早已成為 Java 后端開發的“標配”&#xff0c;本篇文章將帶你全…

【NLP入門系列五】中文文本分類案例

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 博主簡介&#xff1a;努力學習的22級本科生一枚 &#x1f31f;?&#xff1b;探索AI算法&#xff0c;C&#xff0c;go語言的世界&#xff1b;在迷茫中尋找光芒…

【微信小程序】- 監聽全局globalData數據

【微信小程序】- 監聽全局globalData數據 數據劫持&#xff08;Object.defineProperty&#xff09;實現適用場景 數據劫持&#xff08;Object.defineProperty&#xff09; 實現 通過攔截 globalData 的屬性讀寫實現自動監聽&#xff0c;適合精確監聽特定變量。 ?實現步驟?&…

高速公路閑置土地資源化利用:廣西浦北互通3MW分布式光伏監控實踐

摘要&#xff1a; 分布式光伏項目在清潔能源轉型中扮演重要角色&#xff0c;其創新的空間利用模式有助于緩解能源開發與土地資源間的矛盾。廣西大唐至浦北高速公路&#xff08;浦北互通&#xff09;項目&#xff0c;利用高速公路沿線閑置空地建設光伏電站&#xff0c;發揮了分布…

【Linux網絡編程】網絡基礎

目錄 計算機網絡背景 初識協議 網絡協議 協議分層 OSI七層模型 TCP/IP五層(或四層)模型 再識協議 為什么要有TCP/IP協議&#xff1f; 什么是TCP/IP協議&#xff1f; 重談協議 網絡傳輸基本流程 局域網傳輸流程 跨網絡傳輸流程 Socket編程預備 理解源IP地址與目的…

BlenderBot對話機器人大模型Facebook開發

文章目錄 &#x1f680; BlenderBot 的關鍵特性&#x1f9ea; 版本與改進&#x1f4ca; 應用實例 Blender是攪拌機&#xff0c;果汁機&#xff0c;混合機的意思。 BlenderBot 是由 Facebook AI Research (FAIR) 開發的一種先進的對話生成模型。它旨在通過融合多種對話技能&…

60天python訓練計劃----day59

在之前的學習中&#xff0c;我們層層遞進的介紹了時序模型的發展&#xff0c;從AR到MA到ARMA&#xff0c;再到ARIMA。本質就是把數據處理的操作和模型結合在一起了&#xff0c;實際上昨天提到的季節性差分也可以合并到模型中&#xff0c;讓流程變得更加統一。 季節性差分用S來…

學習日志05 python

我相信事在人為&#xff0c;人定勝天&#xff0c;現在還是在基礎語法上面打轉&#xff0c;還是會提出一些很低級的很基礎的問題&#xff0c;不要著急&#xff0c;波浪式前進、螺旋式上升的過程吧&#xff0c;雖然現在的確是很絕望吧...... 今天要做一個練習&#xff1a;編寫猜…

LiteHub中間件之gzip算法

gzip算法理論部分LZ777算法霍夫曼編碼算法改進型的LZ777算法代碼實現壓縮對象gzip實現運行分析日志查看wireshark抓包查看后臺管理界面查看理論部分 gzip是一種無損壓縮算法&#xff0c;其基礎為Deflate&#xff0c;Deflate是LZ77與哈弗曼編碼的一個組合體。它的基本原理是&…