最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL?MVCC(多版本并發(fā)控制)實(shí)現(xiàn)機(jī)制詳細(xì)講解

 更新時(shí)間:2026年06月09日 10:27:21   作者:xiaolyuh123  
MVCC是一種用于管理數(shù)據(jù)庫并發(fā)訪問的技術(shù),它通過在數(shù)據(jù)庫中存儲(chǔ)數(shù)據(jù)的多個(gè)版本來避免讀寫沖突,從而提高了數(shù)據(jù)庫的并發(fā)性能,這篇文章主要介紹了MySQL?MVCC(多版本并發(fā)控制)實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下

前言

MVCC(Multi-Version Concurrency Control,多版本并發(fā)控制)是InnoDB存儲(chǔ)引擎解決讀寫沖突、提升并發(fā)性能的核心技術(shù)——它通過為數(shù)據(jù)行維護(hù)多個(gè)版本(快照),讓讀操作(SELECT)無需加鎖即可讀取數(shù)據(jù),實(shí)現(xiàn)讀不阻塞寫、寫不阻塞讀的高并發(fā)效果。

一、MVCC核心概念

1.1 什么是MVCC

MVCC是InnoDB專為讀已提交(RC)可重復(fù)讀(RR) 隔離級(jí)別設(shè)計(jì)的并發(fā)控制機(jī)制,核心特征如下:

  • 核心思想:為每一行數(shù)據(jù)維護(hù)多個(gè)版本(快照),不同事務(wù)讀取時(shí),根據(jù)規(guī)則選擇對(duì)應(yīng)版本的數(shù)據(jù),而非直接讀取最新數(shù)據(jù);
  • 適用場景:僅針對(duì)快照讀(普通SELECT 生效,當(dāng)前讀(SELECT ```FOR UPDATE/LOCK IN SHARE MODE、INSERT/UPDATE/DELETE)仍需加鎖;
  • 目標(biāo):解決“讀寫沖突”,避免傳統(tǒng)鎖機(jī)制中“讀阻塞寫、寫阻塞讀”的問題,提升并發(fā)性能。

1.2 MVCC的核心目標(biāo)

  • 讀操作無鎖化:快照讀無需加行鎖/表鎖,不阻塞寫操作;
  • 數(shù)據(jù)一致性:保證不同事務(wù)在各自隔離級(jí)別下,讀取到符合規(guī)則的一致數(shù)據(jù);
  • 歷史版本可回溯:通過版本鏈,支持事務(wù)讀取“過去某個(gè)時(shí)間點(diǎn)”的數(shù)據(jù)(如RR隔離級(jí)別的可重復(fù)讀)。

二、MVCC實(shí)現(xiàn)的三大基礎(chǔ)組件

InnoDB的MVCC依賴行記錄隱藏字段、Undo Log(回滾日志)、Read View(讀視圖) 三大核心組件,三者協(xié)同完成多版本數(shù)據(jù)的管理和讀取。

2.1 行記錄的隱藏字段

InnoDB為每一行數(shù)據(jù)(除自定義字段外)自動(dòng)添加3個(gè)隱藏字段,是MVCC的基礎(chǔ):

隱藏字段字段類型核心作用
DB_TRX_ID6字節(jié)記錄最后一次插入/更新該行數(shù)據(jù)的事務(wù)ID(刪除視為特殊的更新,標(biāo)記刪除);
DB_ROLL_PTR7字節(jié)回滾指針,指向該行數(shù)據(jù)的Undo Log版本鏈(通過該指針可回溯歷史版本);
DB_ROW_ID6字節(jié)聚簇索引無主鍵/唯一鍵時(shí),InnoDB自動(dòng)生成的行ID(僅用于標(biāo)識(shí)行,非MVCC核心);

示例

假設(shè)有表user(id INT PRIMARY KEY, name VARCHAR(20)),插入一行(1, '張三'),該行的實(shí)際存儲(chǔ)結(jié)構(gòu)為:

idnameDB_TRX_IDDB_ROLL_PTRDB_ROW_ID
1張三100指向Undo LogNULL

(注:DB_TRX_ID=100表示插入該記錄的事務(wù)ID為100)

2.2 Undo Log(回滾日志)

Undo Log是InnoDB在修改數(shù)據(jù)時(shí),記錄的“數(shù)據(jù)修改前的快照”,是實(shí)現(xiàn)版本鏈的核心載體。

2.2.1 Undo Log的類型

  • Insert Undo Log:僅記錄INSERT操作的日志,事務(wù)提交后可直接刪除(因INSERT的記錄僅當(dāng)前事務(wù)可見,無版本回溯需求);
  • Update Undo Log:記錄UPDATE/DELETE操作的日志,事務(wù)提交后需保留(供其他事務(wù)的MVCC讀取歷史版本),直到?jīng)]有事務(wù)需要訪問該版本時(shí),由Purge線程清理。

2.2.2 版本鏈(Version Chain)

每次更新行數(shù)據(jù)時(shí),InnoDB會(huì)按以下步驟維護(hù)版本鏈:

  1. 將更新前的數(shù)據(jù)寫入Update Undo Log;
  2. 更新行記錄的DB_TRX_ID為當(dāng)前事務(wù)ID;
  3. 更新行記錄的DB_ROLL_PTR,指向剛生成的Update Undo Log;
  4. 多次更新后,DB_ROLL_PTR會(huì)串聯(lián)所有歷史版本,形成版本鏈(鏈頭是最新版本,鏈尾是最早版本)。

版本鏈?zhǔn)纠?/strong>:

當(dāng)前行版本(DB_TRX_ID=102) → DB_ROLL_PTR → 版本1(DB_TRX_ID=101) → DB_ROLL_PTR → 版本0(DB_TRX_ID=100)

2.3 Read View(讀視圖)

Read View是事務(wù)執(zhí)行快照讀時(shí),生成的一個(gè)“可見性判斷規(guī)則”,核心作用是:判斷當(dāng)前事務(wù)能看到哪些版本的數(shù)據(jù)。

2.3.1 Read View的核心字段

Read View包含4個(gè)關(guān)鍵字段,用于版本可見性判斷:

字段名含義
m_ids生成Read View時(shí),當(dāng)前活躍的事務(wù)ID集合(未提交的事務(wù)ID);
min_trx_idm_ids中的最小事務(wù)ID(活躍事務(wù)的最小ID);
max_trx_id系統(tǒng)下一個(gè)要分配的事務(wù)ID(大于當(dāng)前所有已分配的事務(wù)ID);
creator_trx_id創(chuàng)建該Read View的事務(wù)ID(當(dāng)前執(zhí)行快照讀的事務(wù)ID);

2.3.2 版本可見性判斷規(guī)則

事務(wù)讀取行數(shù)據(jù)時(shí),通過Read View判斷該行的某個(gè)版本是否可見:
假設(shè)待判斷版本的DB_TRX_ID = trx_id,規(guī)則如下:

  1. trx_id < min_trx_id:該版本由“已提交的事務(wù)”生成,可見;
  2. trx_id >= max_trx_id:該版本由“未來的事務(wù)”生成(當(dāng)前事務(wù)未開始時(shí),該事務(wù)還未創(chuàng)建),不可見;
  3. min_trx_id ≤ trx_id < max_trx_id
    • trx_id ∈ m_ids:該版本由“當(dāng)前活躍的未提交事務(wù)”生成,不可見
    • trx_id ∉ m_ids:該版本由“已提交的事務(wù)”生成,可見
  4. 若版本不可見,則通過DB_ROLL_PTR回溯版本鏈,直到找到第一個(gè)可見的版本(或無可見版本)。

三、MVCC核心執(zhí)行邏輯(以RR隔離級(jí)別為例)

以MySQL默認(rèn)的可重復(fù)讀(RR) 隔離級(jí)別為例,拆解MVCC在INSERT/UPDATE/DELETE/SELECT中的執(zhí)行流程。

3.1 數(shù)據(jù)插入(INSERT)

  1. 事務(wù)T1(ID=100)執(zhí)行INSERT INTO user(id, name) VALUES (1, '張三');
  2. InnoDB為該行數(shù)據(jù)寫入DB_TRX_ID=100DB_ROLL_PTR=NULL(無歷史版本);
  3. 生成Insert Undo Log(僅用于事務(wù)回滾,提交后刪除);
  4. 事務(wù)提交后,該行數(shù)據(jù)的版本僅對(duì)已提交的事務(wù)可見。

3.2 數(shù)據(jù)更新(UPDATE)

  1. 事務(wù)T2(ID=101)執(zhí)行UPDATE user SET name='李四' WHERE id=1;
  2. InnoDB先將該行當(dāng)前版本(DB_TRX_ID=100)寫入Update Undo Log
  3. 更新行記錄的DB_TRX_ID=101,DB_ROLL_PTR指向剛生成的Update Undo Log
  4. 此時(shí)版本鏈:當(dāng)前版本(101)→ 歷史版本(100);
  5. 事務(wù)提交后,Update Undo Log保留,供其他事務(wù)讀取歷史版本。

3.3 數(shù)據(jù)刪除(DELETE)

DELETE被InnoDB視為“特殊的UPDATE”,執(zhí)行流程如下:

  1. 事務(wù)T3(ID=102)執(zhí)行DELETE FROM user WHERE id=1;
  2. InnoDB將該行當(dāng)前版本寫入Update Undo Log
  3. 更新行記錄的DB_TRX_ID=102,并標(biāo)記“刪除標(biāo)識(shí)”(物理刪除由Purge線程異步完成);
  4. 版本鏈新增一條:當(dāng)前版本(102,標(biāo)記刪除)→ 版本1(101)→ 版本0(100)。

3.4 數(shù)據(jù)讀?。⊿ELECT,快照讀)

假設(shè)當(dāng)前有活躍事務(wù)ID:101、102,事務(wù)T4(ID=103)執(zhí)行SELECT * FROM user WHERE id=1(RR隔離級(jí)別):

  1. T4第一次執(zhí)行SELECT時(shí),生成Read View:
    • m_ids = {101, 102},min_trx_id=101max_trx_id=104,creator_trx_id=103
  2. 讀取行數(shù)據(jù)的當(dāng)前版本(DB_TRX_ID=102),判斷可見性:
    • 102 ≥ min_trx_id(101)102 < max_trx_id(104),且102 ∈ m_ids → 不可見;
  3. 通過DB_ROLL_PTR回溯版本鏈,讀取上一個(gè)版本(DB_TRX_ID=101):
    • 101 ∈ m_ids → 不可見;
  4. 繼續(xù)回溯到版本0(DB_TRX_ID=100):
    • 100 < min_trx_id(101) → 可見;
  5. 返回該版本的數(shù)據(jù)(name='張三');
  6. RR隔離級(jí)別下,T4后續(xù)的SELECT會(huì)復(fù)用該Read View,因此多次讀取結(jié)果一致(可重復(fù)讀)。

四、不同隔離級(jí)別下的MVCC行為

MVCC僅在讀已提交(RC)可重復(fù)讀(RR) 隔離級(jí)別生效,核心區(qū)別是Read View的創(chuàng)建時(shí)機(jī)

隔離級(jí)別Read View創(chuàng)建時(shí)機(jī)讀取結(jié)果特點(diǎn)
讀已提交(RC)每次執(zhí)行快照讀(SELECT)時(shí),重新創(chuàng)建Read View同一事務(wù)內(nèi)多次SELECT可能讀取到不同版本(不可重復(fù)讀),僅能看到已提交的最新版本;
可重復(fù)讀(RR)事務(wù)內(nèi)第一次執(zhí)行快照讀時(shí)創(chuàng)建Read View,后續(xù)復(fù)用同一事務(wù)內(nèi)多次SELECT讀取結(jié)果一致(可重復(fù)讀),僅能看到事務(wù)啟動(dòng)時(shí)已提交的版本;
讀未提交(RU)不使用MVCC,直接讀取最新數(shù)據(jù)(無版本控制)能看到未提交事務(wù)的數(shù)據(jù),存在臟讀;
串行化(SERIALIZABLE)禁用MVCC,所有讀操作加表鎖完全串行執(zhí)行,無并發(fā)沖突,但性能極低;

五、MVCC的優(yōu)勢與局限

5.1 優(yōu)勢

  • 高并發(fā):快照讀無鎖,讀寫互不阻塞,大幅提升并發(fā)性能;
  • 數(shù)據(jù)一致性:在RC/RR隔離級(jí)別下,保證讀取數(shù)據(jù)的一致性,避免臟讀(RC/RR)、不可重復(fù)讀(RR);
  • 無鎖讀:無需加行鎖/表鎖,減少鎖競爭和死鎖概率。

5.2 局限

  • 版本鏈開銷:大量更新操作會(huì)導(dǎo)致版本鏈過長,增加讀取時(shí)的回溯成本;
  • Undo Log清理:Purge線程需異步清理過期的Undo Log,若清理不及時(shí)會(huì)占用磁盤空間;
  • 僅適用于快照讀:當(dāng)前讀(如SELECT ```FOR UPDATE)仍需加鎖,無法避免寫沖突。

總結(jié)

  1. 核心依賴:MVCC基于行記錄隱藏字段(DB_TRX_ID/DB_ROLL_PTR)、Undo Log版本鏈、Read View可見性規(guī)則實(shí)現(xiàn);
  2. 核心邏輯:更新數(shù)據(jù)時(shí)生成版本鏈,讀取數(shù)據(jù)時(shí)通過Read View判斷版本可見性,回溯版本鏈找到符合規(guī)則的版本;
  3. 隔離級(jí)別差異:RC每次SELECT創(chuàng)建Read View(不可重復(fù)讀),RR僅第一次創(chuàng)建(可重復(fù)讀);
  4. 核心價(jià)值:實(shí)現(xiàn)“讀不阻塞寫、寫不阻塞讀”,是InnoDB高并發(fā)的核心保障。

到此這篇關(guān)于MySQL MVCC(多版本并發(fā)控制)實(shí)現(xiàn)機(jī)制的文章就介紹到這了,更多相關(guān)MySQL MVCC多版本并發(fā)控制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • DBeaver導(dǎo)入.sql后綴文件詳細(xì)圖文教程

    DBeaver導(dǎo)入.sql后綴文件詳細(xì)圖文教程

    DBeaver是一款數(shù)據(jù)庫管理工具,最重要的是他是一款比較好的開源工具,這篇文章主要介紹了DBeaver導(dǎo)入.sql后綴文件的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2025-12-12
  • MySQL學(xué)習(xí)之索引及優(yōu)化

    MySQL學(xué)習(xí)之索引及優(yōu)化

    這篇文章主要介紹MySQL的索引及優(yōu)化,索引是幫助MySQL進(jìn)行高效查詢的一種數(shù)據(jù)結(jié)構(gòu)。好比一本書的目錄,能加快查詢的速度,想進(jìn)一步了解的小伙伴可以詳細(xì)閱讀本文
    2023-03-03
  • mysql數(shù)據(jù)庫id主鍵自增加刪除后不連續(xù)如何解決

    mysql數(shù)據(jù)庫id主鍵自增加刪除后不連續(xù)如何解決

    這篇文章主要介紹了mysql數(shù)據(jù)庫id主鍵自增加刪除后不連續(xù)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • windows10安裝mysql5.7.17教程

    windows10安裝mysql5.7.17教程

    windows10安裝mysql5.7.17是這樣安裝的嗎?這篇文章主要為大家詳細(xì)介紹了win10下mysql5.7.17安裝配置方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 詳解mysql數(shù)據(jù)庫中文亂碼問題

    詳解mysql數(shù)據(jù)庫中文亂碼問題

    這篇文章主要介紹了詳解mysql數(shù)據(jù)庫中文亂碼問題的相關(guān)資料,需要的朋友可以參考下
    2017-10-10
  • 分組查詢GROUP BY的使用與SQL執(zhí)行順序的講解

    分組查詢GROUP BY的使用與SQL執(zhí)行順序的講解

    今天小編就為大家分享一篇關(guān)于分組查詢GROUP BY的使用與SQL執(zhí)行順序的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • MySQL表的CURD操作(數(shù)據(jù)的增刪改查)

    MySQL表的CURD操作(數(shù)據(jù)的增刪改查)

    數(shù)據(jù)庫本質(zhì)上是一個(gè)文件系統(tǒng),通過標(biāo)準(zhǔn)的SQL語句對(duì)數(shù)據(jù)進(jìn)行CURD操作,下面這篇文章主要給大家介紹了關(guān)于MySQL表的CURD操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • MySQL實(shí)現(xiàn)數(shù)據(jù)更新的示例詳解

    MySQL實(shí)現(xiàn)數(shù)據(jù)更新的示例詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL實(shí)現(xiàn)數(shù)據(jù)更新的相關(guān)資料,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Mysql 索引從入門到精通(從原理到實(shí)踐)

    Mysql 索引從入門到精通(從原理到實(shí)踐)

    本文介紹MySQL索引深度解析:從原理到實(shí)踐,本文涵蓋索引基礎(chǔ)概念、類型、底層原理及管理策略,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • MySQL四種備份表的實(shí)現(xiàn)方式

    MySQL四種備份表的實(shí)現(xiàn)方式

    本文主要介紹了MySQL四種備份表的實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02

最新評(píng)論

五河县| 南漳县| 黄陵县| 芜湖县| 阳城县| 峨眉山市| 元氏县| 昆山市| 曲松县| 科尔| 连山| 晋宁县| 石狮市| 宜君县| 麻江县| 绥芬河市| 天镇县| 洛川县| 九江县| 新疆| 五常市| 西城区| 高青县| 视频| 柘城县| 健康| SHOW| 邢台市| 沛县| 泰来县| 南澳县| 太康县| 金乡县| 江安县| 白河县| 大宁县| 云龙县| 中宁县| 道孚县| 柏乡县| 韶山市|