偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

CMU15-445 數(shù)據(jù)庫系統(tǒng)播客:深入理解多版本并發(fā)控制 (MVCC) - 現(xiàn)代數(shù)據(jù)庫的并發(fā)基石

數(shù)據(jù)庫 其他數(shù)據(jù)庫
MVCC 不僅僅是一個(gè)技術(shù)術(shù)語,它是一種精妙的設(shè)計(jì)哲學(xué),是現(xiàn)代數(shù)據(jù)庫能夠在高并發(fā)世界中保持優(yōu)雅和高效的關(guān)鍵。它通過多版本的“時(shí)空”換取了讀寫并發(fā)的“自由”,但其實(shí)現(xiàn)背后充滿了深刻的權(quán)衡。

構(gòu)建任何高并發(fā)應(yīng)用時(shí),數(shù)據(jù)庫的性能和穩(wěn)定性都是我們關(guān)注的重中之重。而談到數(shù)據(jù)庫,一個(gè)我們無法繞開的概念就是 并發(fā)控制 。今天,我們將深入探討現(xiàn)代關(guān)系型數(shù)據(jù)庫中最主流的并發(fā)控制思想—— 多版本并發(fā)控制(Multi-Version Concurrency Control, MVCC) 。

無論是 PostgreSQL, MySQL (InnoDB), Oracle, 還是 SQL Server(在特定隔離級(jí)別下),MVCC 都是它們處理高并發(fā)讀寫請(qǐng)求、保證數(shù)據(jù)一致性的核心機(jī)制。

核心思想:MVCC 是什么?

許多初學(xué)者可能會(huì)誤解,認(rèn)為 MVCC 是一種與兩階段鎖(2PL)或樂觀并發(fā)控制(OCC)并列的并發(fā)控制“協(xié)議”。但一個(gè)更精確的定義是: MVCC 是一種實(shí)現(xiàn)并發(fā)控制的系統(tǒng)架構(gòu)(System Architecture) 。

它的核心理念極其優(yōu)雅: 通過保留數(shù)據(jù)的多個(gè)歷史版本,來實(shí)現(xiàn)讀寫操作的并行不悖 。

想象一下傳統(tǒng)的鎖機(jī)制:當(dāng)一個(gè)事務(wù)正在寫入某行數(shù)據(jù)時(shí),這行數(shù)據(jù)就會(huì)被“鎖”住。此時(shí),其他任何想要讀取這行數(shù)據(jù)的事務(wù)都必須等待,直到寫事務(wù)提交或回滾。同樣,一個(gè)事務(wù)在讀取數(shù)據(jù)時(shí),也可能阻塞其他事務(wù)的寫入。這種讀寫相互阻塞的模式,在并發(fā)量高的場(chǎng)景下會(huì)嚴(yán)重影響系統(tǒng)吞吐量。

MVCC 則徹底改變了這一游戲規(guī)則。它的核心承諾是:

寫操作不阻塞讀操作,讀操作也不阻塞寫操作。

這是如何實(shí)現(xiàn)的呢?當(dāng)一個(gè)事務(wù)需要讀取數(shù)據(jù)時(shí),系統(tǒng)不會(huì)直接返回“最新”的數(shù)據(jù),而是為其提供一個(gè) “一致性快照(Consistent Snapshot)” 。這個(gè)快照代表了該事務(wù)啟動(dòng)時(shí),整個(gè)數(shù)據(jù)庫的某個(gè)一致性狀態(tài)。如此一來,即使其他事務(wù)正在修改數(shù)據(jù),當(dāng)前事務(wù)讀取的也只是它自己快照中的、未被修改的舊版本,完全不受干擾。

然而,需要明確的是,MVCC 自身并不解決 寫-寫沖突(Write-Write Conflicts) 。當(dāng)兩個(gè)事務(wù)嘗試修改 同一個(gè) 數(shù)據(jù)對(duì)象時(shí),系統(tǒng)仍然需要一個(gè)仲裁機(jī)制來決定誰勝誰負(fù)。這時(shí),MVCC 架構(gòu)就需要與一個(gè)傳統(tǒng)的并發(fā)控制協(xié)議(如時(shí)間戳排序、樂觀鎖或兩階段鎖)相結(jié)合,來處理這類沖突。

歷史回眸:一個(gè)經(jīng)久不衰的理念

MVCC 的思想并非憑空出現(xiàn)。它的理論雛形最早可以追溯到 1978 年麻省理工學(xué)院(MIT)的一篇博士論文 。但真正將其工程化并推向市場(chǎng)的,是 20 世紀(jì) 80 年代早期的 DEC 公司 。

DEC 公司開發(fā)的兩款數(shù)據(jù)庫產(chǎn)品—— Rdb/VMS 和 InterBase ,是商業(yè)上最早成功實(shí)現(xiàn) MVCC 的系統(tǒng)。這背后的關(guān)鍵人物是 Jim Starkey ,他不僅是 MVCC 的早期實(shí)踐者,還被認(rèn)為是 BLOBs(二進(jìn)制大對(duì)象)和數(shù)據(jù)庫觸發(fā)器的發(fā)明人。

這段歷史還有一些有趣的后續(xù):

  • DEC 的 Rdb/VMS 最終被 Oracle 收購,成為了 Oracle Rdb。
  • InterBase 在幾經(jīng)易手后被開源,演變成了今天我們所熟知的 Firebird 數(shù)據(jù)庫。

一個(gè)有趣的花絮是:Mozilla 最初想將瀏覽器命名為 Phoenix,因版權(quán)沖突改為 Firebird,但再次與 Firebird 數(shù)據(jù)庫重名,最終才定名為我們熟悉的 Firefox。

MVCC 的兩大殺手級(jí)優(yōu)勢(shì)

為什么 MVCC 能夠經(jīng)受住時(shí)間的考驗(yàn),成為現(xiàn)代數(shù)據(jù)庫的標(biāo)配?因?yàn)樗鼛砹藘蓚€(gè)無與倫比的優(yōu)勢(shì):

極致高效的只讀事務(wù)

在 MVCC 架構(gòu)下,只讀事務(wù)的執(zhí)行速度快得驚人。當(dāng)一個(gè)事務(wù)被聲明為只讀(Read-Only)時(shí),數(shù)據(jù)庫系統(tǒng)知道它絕不會(huì)修改數(shù)據(jù)。因此,系統(tǒng)無需為其獲取任何鎖,也無需追蹤其讀寫集。它要做的僅僅是讀取其事務(wù)開始時(shí)那個(gè)“一致性快照”。這幾乎是零成本的并發(fā),極大地提升了讀多寫少場(chǎng)景下的系統(tǒng)性能。

強(qiáng)大的“時(shí)間旅行”查詢能力

由于 MVCC 天然地保存了數(shù)據(jù)的歷史版本,它為實(shí)現(xiàn)“時(shí)間旅行查詢(Time-Travel Queries)”提供了可能。這意味著你可以向數(shù)據(jù)庫提出這樣的問題:

  • “三天前,我們的用戶表是什么狀態(tài)?”
  • “上個(gè)季度末,公司的總銷售額是多少?”

這個(gè)概念最早由 Postgres 在 20 世紀(jì) 80 年代提出。但遺憾的是,除了特定領(lǐng)域的數(shù)據(jù)庫外,大多數(shù)通用數(shù)據(jù)庫系統(tǒng)并沒有完全開放這個(gè)功能。主要原因在于成本:支持任意時(shí)間點(diǎn)的查詢意味著 必須永久保留所有歷史版本 ,這將導(dǎo)致存儲(chǔ)空間的無限膨脹。

盡管如此,在某些對(duì)數(shù)據(jù)審計(jì)和歷史追溯有強(qiáng)需求的領(lǐng)域(如 金融行業(yè) ),時(shí)間旅行查詢的價(jià)值巨大。法規(guī)可能要求金融機(jī)構(gòu)保留長(zhǎng)達(dá)數(shù)年的交易記錄,MVCC 使得在這海量歷史數(shù)據(jù)中進(jìn)行查詢變得異常高效。

深入實(shí)現(xiàn):MVCC 的四大核心設(shè)計(jì)決策

實(shí)現(xiàn)一個(gè)健壯高效的 MVCC 系統(tǒng),遠(yuǎn)比聽起來復(fù)雜。數(shù)據(jù)庫開發(fā)者必須在四個(gè)關(guān)鍵領(lǐng)域做出精心的設(shè)計(jì)和權(quán)衡。

并發(fā)控制協(xié)議 (Concurrency Control Protocol)

如前所述,MVCC 架構(gòu)需要一個(gè)“伙伴”協(xié)議來處理寫-寫沖突。不同的數(shù)據(jù)庫選擇了不同的方案:

  • 時(shí)間戳排序 (Timestamp Ordering, T/O) : 每個(gè)事務(wù)獲取一個(gè)時(shí)間戳,系統(tǒng)根據(jù)時(shí)間戳的先后順序來決定事務(wù)的執(zhí)行次序。
  • 樂觀并發(fā)控制 (Optimistic Concurrency Control, OCC) : 事務(wù)執(zhí)行期間不做任何檢查,直到提交時(shí)才檢查是否存在沖突。如果沖突,則回滾。
  • 兩階段鎖 (Two-Phase Locking, 2PL) : 仍然使用鎖來解決寫-寫沖突,但讀操作不受影響。

這個(gè)協(xié)議的選擇,直接決定了數(shù)據(jù)庫在不同沖突場(chǎng)景下的行為和性能。

版本存儲(chǔ) (Version Storage)

這是 MVCC 實(shí)現(xiàn)中最核心的部分:如何組織和存儲(chǔ)一個(gè)邏輯數(shù)據(jù)的多個(gè)物理版本?通常,系統(tǒng)會(huì)為每個(gè) 邏輯元組(Logical Tuple) 維護(hù)一個(gè) 版本鏈(Version Chain) ,而索引指向這個(gè)鏈的“頭部”。

主要有三種主流方案:

僅追加存儲(chǔ) (Append-Only Storage)

這是最直觀的方式,也是 PostgreSQL 采用的策略。當(dāng)一個(gè)元組被更新時(shí),系統(tǒng)不會(huì)在原地修改它,而是:

  1. 將舊版本的完整內(nèi)容復(fù)制一份,形成一個(gè)新的物理元組。
  2. 在這個(gè)新的物理元組上執(zhí)行修改。
  3. 將版本鏈的指針指向這個(gè)新版本。

這種方式又引申出版本鏈的組織順序問題:

  • 從舊到新 (Oldest-to-Newest, O2N) : 新版本追加在鏈表的末尾。優(yōu)點(diǎn)是追加操作簡(jiǎn)單;缺點(diǎn)是查找最新版本時(shí)可能需要遍歷整個(gè)鏈。
  • 從新到舊 (Newest-to-Oldest, N2O) : 新版本放在鏈表的頭部。優(yōu)點(diǎn)是查找最新版本非??欤∣(1));缺點(diǎn)是每次創(chuàng)建新版本,所有指向舊頭部的索引都必須更新為指向新頭部,更新開銷較大。

權(quán)衡分析 :僅追加存儲(chǔ)的 讀取舊版本性能極好 ,因?yàn)榕f元組是完整獨(dú)立的,無需任何計(jì)算。但其 寫入開銷較大 ,即使只修改一個(gè)字段,也需要復(fù)制整個(gè)元組。

時(shí)間旅行存儲(chǔ) (Time-Travel Storage)

這種方案將主表和歷史表分開。主表上永遠(yuǎn)只保存最新版本的數(shù)據(jù)。當(dāng)數(shù)據(jù)被更新時(shí),舊版本被復(fù)制到一個(gè)獨(dú)立的 “時(shí)間旅行表” 中。這種方式邏輯清晰,但可能增加數(shù)據(jù)管理的復(fù)雜性。

Delta 存儲(chǔ) (Delta Storage)

這是 MySQL (InnoDB) 和 Oracle 采用的策略。其思想類似于 Git 的 diff:不存儲(chǔ)完整的舊版本,而 只記錄被修改字段的“增量(Delta)” 。

當(dāng)一個(gè)元組被更新時(shí),系統(tǒng)會(huì)將修改前的“舊值”存放到一個(gè)獨(dú)立的 Delta 存儲(chǔ)區(qū)(在 InnoDB 中稱為 Rollback Segment),然后在主表上進(jìn)行原地更新。版本鏈實(shí)際上是通過指針串聯(lián)起來的 Delta 記錄。

權(quán)衡分析 :Delta 存儲(chǔ)的 寫入性能通常更高 ,因?yàn)橹恍鑿?fù)制少量修改的字段,而非整個(gè)元組。但其 讀取舊版本的開銷更大 ,因?yàn)樾枰獜淖钚掳姹鹃_始,通過“重放(Replay)”一系列的 Delta 記錄來逐步回溯,才能重建出目標(biāo)歷史版本。

性能對(duì)決的根源 :正是由于版本存儲(chǔ)策略的根本不同,我們經(jīng)常觀察到:在讀密集型,特別是需要讀取歷史數(shù)據(jù)的分析場(chǎng)景下, PostgreSQL 可能表現(xiàn)更優(yōu);而在寫密集型,特別是更新操作頻繁的 OLTP 場(chǎng)景下, MySQL (InnoDB) 可能更具優(yōu)勢(shì)。

垃圾回收 (Garbage Collection)

隨著系統(tǒng)運(yùn)行,會(huì)產(chǎn)生大量不再需要的舊版本(例如,所有活躍事務(wù)都無法再看到它們,或者由已中止事務(wù)創(chuàng)建的版本)。垃圾回收機(jī)制(常被稱為 VACUUM)負(fù)責(zé)清理這些“垃圾”以回收磁盤空間。

何時(shí)可以回收? 一個(gè)版本可以被安全回收的條件是:當(dāng)前系統(tǒng)中沒有任何一個(gè)活躍事務(wù)的“快照時(shí)間戳”會(huì)落在該版本的生命周期內(nèi)。

如何高效回收?

  • 后臺(tái)清掃 (Background Vacuuming) : 由一個(gè)或多個(gè)專用后臺(tái)線程定期掃描表,查找并清理無效版本。為了避免全表掃描的巨大開銷,系統(tǒng)通常會(huì)維護(hù)一個(gè) “臟頁位圖(Dirty Page Bitmap)” ,只檢查那些被修改過的數(shù)據(jù)頁。這是 PostgreSQL 的主要方式。
  • 協(xié)作式清理 (Cooperative Cleaning) : 工作線程在執(zhí)行查詢、遍歷版本鏈的過程中,“順手”清理掉它們遇到的無效舊版本。這種方式非常巧妙,但它 僅適用于從舊到新(O2N)的版本鏈 ,因?yàn)橹挥性谶@種順序下,查找新版本才會(huì)自然地經(jīng)過舊版本。

索引管理 (Index Management)

在 MVCC 中,索引不僅要能找到數(shù)據(jù),還要能找到 正確版本 的數(shù)據(jù)。

主鍵索引 (Primary Key Indexes) : 通常比較直接,索引條目直接指向版本鏈的頭部。如果主鍵本身被更新,系統(tǒng)通常將其處理為一次 DELETE + 一次 INSERT。

二級(jí)索引 (Secondary Indexes) : 處理起來要復(fù)雜得多,直接影響數(shù)據(jù)庫的性能特征。

  • 物理指針 (Physical Pointers) : 二級(jí)索引的葉子節(jié)點(diǎn)直接存儲(chǔ)元組的物理地址(如:頁ID + 頁內(nèi)偏移量)。這是 PostgreSQL 的典型實(shí)現(xiàn)。

a.優(yōu)點(diǎn) : 查詢速度快。通過二級(jí)索引能一次性定位到數(shù)據(jù),無需額外查找。

b.缺點(diǎn) : 更新開銷大。在 PostgreSQL 的僅追加模型中,一次 UPDATE 會(huì)導(dǎo)致元組產(chǎn)生新的物理位置。這意味著, 所有 指向該元組的二級(jí)索引(可能有很多個(gè))都必須被更新,這在寫密集型負(fù)載下會(huì)成為巨大的性能瓶頸。

  • 邏輯指針 (Logical Pointers) : 二級(jí)索引的葉子節(jié)點(diǎn)存儲(chǔ)的是一個(gè)不變的邏輯標(biāo)識(shí)符,通常是 主鍵的值 。這是 MySQL (InnoDB) 的實(shí)現(xiàn)方式。

a.優(yōu)點(diǎn) : 更新開銷小。當(dāng)元組更新(即使物理位置改變)時(shí),只要主鍵不變,所有二級(jí)索引都 無需改動(dòng) 。這極大地提升了寫入性能。

b.缺點(diǎn) : 查詢需要“回表”。通過二級(jí)索引查找時(shí),只能先找到主鍵值,然后必須再回到主鍵索引(聚簇索引)中進(jìn)行第二次查找,才能定位到最終的數(shù)據(jù)。這增加了一次額外的索引查找開銷。

總結(jié)

MVCC 不僅僅是一個(gè)技術(shù)術(shù)語,它是一種精妙的設(shè)計(jì)哲學(xué),是現(xiàn)代數(shù)據(jù)庫能夠在高并發(fā)世界中保持優(yōu)雅和高效的關(guān)鍵。它通過多版本的“時(shí)空”換取了讀寫并發(fā)的“自由”,但其實(shí)現(xiàn)背后充滿了深刻的權(quán)衡。

從版本存儲(chǔ)(Append-Only vs. Delta)到索引管理(物理指針 vs. 邏輯指針),每一個(gè)設(shè)計(jì)決策都直接影響了數(shù)據(jù)庫(如 PostgreSQL 和 MySQL)在不同應(yīng)用場(chǎng)景下的性能表現(xiàn)。理解這些內(nèi)在機(jī)制,不僅能幫助我們更好地選擇和使用數(shù)據(jù)庫,更能讓我們?cè)谶M(jìn)行系統(tǒng)設(shè)計(jì)和性能優(yōu)化時(shí),做到胸有成竹,游刃有余。

責(zé)任編輯:武曉燕 來源: Piper蛋窩
相關(guān)推薦

2025-08-18 01:01:00

樂觀并發(fā)控制

2025-08-18 05:11:00

數(shù)據(jù)庫系統(tǒng)播客

2025-08-07 07:31:42

2025-08-11 02:00:00

2025-08-12 07:31:11

2025-08-14 07:32:42

2025-08-04 06:00:00

2025-08-11 02:25:00

數(shù)據(jù)庫數(shù)據(jù)模型

2025-08-21 06:39:13

2025-08-18 07:32:23

2025-08-11 07:31:40

2025-08-26 03:15:00

2025-08-06 00:00:00

2025-08-06 01:22:00

2025-08-22 06:49:20

2025-08-04 07:31:30

2025-08-08 07:37:07

2025-08-26 02:12:00

2025-08-13 07:31:18

2011-08-17 10:11:34

MySQL數(shù)據(jù)庫MVCC
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)