關于 MVCC 的基礎

作為第一篇對 MVCC 的學習材料,以下內容翻譯自 Wikipedia。

1. 什么是MVCC

1.1 基礎概念

MVCC,Multi-Version Concurrency Control,多版本并發控制。MVCC 是一種并發控制的方法,一般在數據庫管理系統中,實現對數據庫的并發訪問;在編程語言中實現事務內存。

如果有人從數據庫中讀數據的同時,有另外的人寫入數據,有可能讀數據的人會看到『半寫』或者不一致的數據。有很多種方法來解決這個問題,叫做并發控制方法。最簡單的方法,通過加鎖,讓所有的讀者等待寫者工作完成,但是這樣效率會很差。MVCC 使用了一種不同的手段,每個連接到數據庫的讀者,在某個瞬間看到的是數據庫的一個快照,寫者寫操作造成的變化在寫操作完成之前(或者數據庫事務提交之前)對于其他的讀者來說是不可見的。

當一個 MVCC 數據庫需要更一個一條數據記錄的時候,它不會直接用新數據覆蓋舊數據,而是將舊數據標記為過時(obsolete)并在別處增加新版本的數據。這樣就會有存儲多個版本的數據,但是只有一個是最新的。這種方式允許讀者讀取在他讀之前已經存在的數據,即使這些在讀的過程中半路被別人修改、刪除了,也對先前正在讀的用戶沒有影響。這種多版本的方式避免了填充刪除操作在內存和磁盤存儲結構造成的空洞的開銷,但是需要系統周期性整理(sweep through)以真實刪除老的、過時的數據。對于面向文檔的數據庫(Document-oriented database,也即半結構化數據庫)來說,這種方式允許系統將整個文檔寫到磁盤的一塊連續區域上,當需要更新的時候,直接重寫一個版本,而不是對文檔的某些比特位、分片切除,或者維護一個鏈式的、非連續的數據庫結構。

MVCC 提供了時點(point in time)一致性視圖。MVCC 并發控制下的讀事務一般使用時間戳或者事務 ID去標記當前讀的數據庫的狀態(版本),讀取這個版本的數據。讀、寫事務相互隔離,不需要加鎖。讀寫并存的時候,寫操作會根據目前數據庫的狀態,創建一個新版本,并發的讀則依舊訪問舊版本的數據。

一句話講,MVCC就是用 同一份數據臨時保留多版本的方式 的方式,實現并發控制。

這里留意到 MVCC 關鍵的兩個點:

  1. 在讀寫并發的過程中如何實現多版本;
  2. 在讀寫并發之后,如何實現舊版本的刪除(畢竟很多時候只需要一份最新版的數據就夠了);

1.2 實現

MVCC 使用時間戳(TS)、遞增的事務 ID(T)實現事務一致性。

MVCC 通過維護多版本數據,保證一個讀事務永遠不會被阻塞。對象 P 維護有多個版本,每個版本會有一個讀時間戳(Read TimeStamp, RTS)和 寫時間戳(Write TimeStamp, WTS),事務 Ti 讀對象 P 的最新版本,該版本早于事務 Ti 的讀時間戳 RTS(Ti)。

事務 Ti 要對 P 執行寫操作,如果有其他事務 Tk 同時對 P 操作,則 RTS(Ti)必須要早于 RTS(Tk),即有 RTS(Ti) < RTS(Tk),這樣對 Ti 對 P 的寫操作才能完成。一般地,如果其他事務擁有 P 的一個更早的讀時間戳的情況下,寫操作是不能完成的。打個比方就是在存儲前面有一道線,只有等你前面的人的完成了他們的事務,你的修改事務才可以提交完成。

重復說一下:每個對象 P 有一個時間戳 TS,如果事務 Ti 想要對 P 執行寫操作,(寫要先讀)事務的讀時間戳是 RTS(Ti),如果有其他事務擁有一個比較早的時間戳,有 TS(P) < RTS(Ti),這時事務 Ti 會退出并重新開始。否則,事務 Ti 創建一個 P 的新版本,并設置新版本 P 的時間戳,似的 TS = TS(Ti)。

MVCC 系統明顯的缺點是會存儲多個版本數據的冗余開銷。但同時,讀操作永不會被阻塞,這對那些以讀操作為主的數據庫來說非常重要。MVCC 實現了真的快照隔離(snapshot isolation),然后其他的并發控制方法要么是不完整的快照隔離方式,要么需要較高的性能損耗。

Wikipedia 中的內容有點繁瑣,簡單地,上面的描述,闡明了在同一數據版本下寫操作的限制,已經通過多版本實現快照隔離的優越性。

1.3 示例

TimeObject1Object2
0"Foo" by T0"Bar" by T0
1"Hello" by T1

Time=1的時候數據庫的狀態如上:

T0 寫 Object1 為 "Foo",寫 Object2 為 "Bar";之后 T1 寫 Object1 為 "Hello",保留 Object2 為原始值。 Object1 的新值將取代 Time=0 時刻的舊值,并提供給 T1提交之后的發生的所有事務。Object1的版本號為0的舊數據會被 GC 掉。

如果有一個長事務 T2,在 T1之后對 Object1和 Object2 進行讀操作,同時并行地,有事務 T3 做更新:刪除 Object2、增加 Object3="Foo-Bar",在 Time=2 數據的狀態如下所示:

TimeObject1Object2Object3
0"Foo" by T0"Bar" by T0
1"Hello" by T1
2(delete)by T3"Foo-Bar" by T3

Time=2 Object2有一個新版本:標記刪除,同時增加了新對象 Object3 。T2 和 T3 并發執行,T2 看到的是數據在 Time=2 且 T3提交前的版本,這樣 T2讀到了 Object2="Bar""Object1="Hello"

以上就是 MVCC 在不加鎖的情況下實現的快照隔離的讀的原理。

1.4 歷史

最早于1978年,論文『Naming and Synchronization in a Decentralized Computer System』清晰地介紹了 MVCC,這是公認關于 MVCC 最早的工作。

在1981年,論文『Concurrency Control in Distributed Database System』介紹MVCC的一些細節。

目前支持 MVCC 的數據庫,包括 DB2、Oracle、Sybase、SQL Server、MySQL、PG 等所有主流數據庫,以及 HBase、Couchbase、Berkeley DB 等 NoSQL 數據庫

參考

  1. Wikipedia: Multiversion concurrency control
  2. List of databases using MVCC

轉載于:https://www.cnblogs.com/YFYkuner/p/5178684.html

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

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

相關文章

集成測試CDI 1.0和Spring 3.1中的作用域bean

在這篇博客文章中&#xff0c;我描述了如何在Spring和CDI中使用作用域bean進行集成測試。 一切都用小代碼示例進行說明。 使用范圍進行集成測試并不是特別容易。 想象一下存在于會話范圍內的bean&#xff0c;例如UserCredentials 。 在集成測試中&#xff0c;通常沒有HttpReque…

JavaScript學習隨記——數組一

數組的創建及length屬性 <script type"text/javascript" charset"utf-8">// 數組創建方式一,此種方式寫的時候比較麻煩var arrnew Array();// 數組創建方式二var arr [1,2,3,4,true,str,new Date()];console.log("arr.length&#xff1a;"…

USACO milk4 枚舉答案再檢驗

剛開始寫了一個暴力的dfs超時了&#xff0c; 最后看了下題解說是先枚舉答案再判斷&#xff0c;然后就寫了雙dfs&#xff0c;全部秒殺&#xff0c;代碼如下&#xff1a; /*ID: m1500293LANG: CPROG: milk4 */ #include <cstdio> #include <cstring> #include <al…

微信小程序常見問題集合(長期更新)

最新更新&#xff1a; 新手跳坑系列&#xff1a;推薦閱讀&#xff1a;《二十四》request:fail錯誤&#xff08;含https解決方案&#xff09;&#xff08;真機預覽問題 跳坑指南《七十》如何讓微信小程序服務類目審核通過跳坑六十九&#xff1a;uploadFile:fail Error: unable t…

mysql指令按順序排列_mysql基本語法大全

1.備份數據庫&#xff1a;1.1備份數據庫中的表:mysqldump -u root -p test a b >d:\bank_a.sql//分別備份數據庫test下a和b表1.2備份一個數據庫mysqldump -u root -p test > d:\testbk.sql1.3備份多個數據庫mysqldump -u root -p --databases test mysql > D:\data.sq…

Spring和石英:多作業計劃服務

作業調度對于應用程序來說是如此重要。 尤其是在大型項目中&#xff0c;處理大量工作可能是一個問題。 Spring和Quartz為解決該問題帶來了巨大的好處。 本文介紹了如何通過使用Spring和Quartz輕松地計劃多個作業。 二手技術&#xff1a; JDK 1.6.0_21 春天3.1.1 石英1.8.5 M…

JavaScript學習隨記——數組二

數組indexOf(arg) 和 lastIndexOf(arg)方法使用 <script type"text/javascript" charset"utf-8">/*** indexOf(arg):返回指定參數在數組中的索引位置&#xff08;從前往后查&#xff0c;比較是使用 ‘’&#xff0c;查詢到立即返回索引位置&#xff…

反射的簡單應用

首先有一個類 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Threading.Tasks;6 7 namespace ConsoleApplication18 {9 public class demo 10 { 11 public string name "程序員"; 12…

JavaFX 2.0示例介紹書

我最近完成了有關JavaFX 2.0 SDK新版本的書的編寫&#xff0c;并且已經將它放在您附近的書店&#xff08; Amazon &#xff09;的書架上。 該書將逐步指導您完成JavaFX 2.0的來龍去脈。 當您遇到一章時&#xff0c;將看到一些菜譜&#xff0c;這些菜譜將帶來一個問題&#xff0…

雙縱坐標的繪圖命令_工程師繪圖必備軟件——OriginLab 2019b

點擊右上角關注&#xff0c;盡享后續精品軟件OriginLab 2019b是OriginLab OriginPro 2019版本的加強版&#xff0c;這個軟件對于許多人來講并不陌生&#xff0c;可以說是科學家和工程師的繪圖必備軟件。新的版本也帶來許多改變&#xff0c;軟件擁有多種功能&#xff0c;這個版本…

JavaScript學習隨記——對象

JS中對象基本使用 <script type"application/javascript" charset"utf-8">//Objcet 所有類的基礎類/*** 創建對象方式一*/ // var objnew Objcet();/** 創建對象方式二,注意 {}不可忘記寫* */var obj {};obj.name "什碼情況";obj.age …

[轉]Java_List元素的遍歷和刪除

原文地址:http://blog.csdn.net/insistgogo/article/details/19619645 1、創建一個ArrayList [java] view plainList<Integer> list new ArrayList<Integer>(); 2、List常用的遍歷方法有三種&#xff1a; &#xff08;1&#xff09;下標循環 [java] view plainfo…

分層設計 --java中的幾種包

對于剛接觸包分層的同學&#xff0c;下面簡單介紹一下java中各個層次&#xff1a; Modle 模型層 &#xff1a;存放你的實體類 dao&#xff1a;主要做數據庫的交互工作&#xff0c;具體的增刪改查等方法&#xff0c;操作數據庫的&#xff1b;這里也可以存放查詢所有的信息接口 …

Spring遠程支持和開發RMI服務

Spring遠程支持簡化了啟用遠程服務的開發。 當前&#xff0c;Spring支持以下遠程技術&#xff1a;遠程方法調用&#xff08;RMI&#xff09;&#xff0c;HTTP調用程序&#xff0c;Hessian&#xff0c;Burlap&#xff0c;JAX-RPC&#xff0c;JAX-WS和JMS。 遠程方法調用&#xf…

cesium繪制網格_Cesium學習筆記-工具篇37-風場繪制

這兩天重新接觸到流場&#xff0c;于是研究下&#xff0c;在大牛們的輪子上也算實現了效果&#xff1a;1二維2三維主要參考以下三篇文章&#xff1a;《WebGL風向圖》給出制作風向圖通常步驟&#xff1a;1. 在屏幕上生成一系列隨機粒子位置并繪制粒子。2. 對于每一個粒子&#x…

ToString:身份哈希碼的十六進制表示形式

我以前在方便的Apache Commons ToStringBuilder上寫過博客&#xff0c;最近有人問我&#xff0c;在生成的String輸出中出現的看似神秘的文本是什么構成的。 詢問該問題的同事正確地推測出他正在查看的是哈希碼&#xff0c;但與他實例的哈希碼不匹配。 我解釋說ToStringBuilder將…

HTML+CSS筆記 CSS中級 縮寫入門

盒子模型代碼簡寫回憶盒模型時外邊距(margin)、內邊距(padding)和邊框(border)設置上下左右四個方向的邊距是按照順時針方向設置的&#xff1a;上右下左。語法:margin:10px 15px 12px 14px;/*上設置為10px、右設置為15px、下設置為12px、左設置為14px*/通常有三種縮寫的方法:1、…

JavaScript學習隨記——常見全局對象屬性及方法

<script type"text/javascript" charset"utf-8">//全局對象&#xff1a; Object、Array、Math等/*** 全局的方法&#xff1a;* 1.encodeURI、escape、decodeURIComponet 編碼* 2.decodeURI、unescape、encodeURIComponet 解碼* 3.parseInt、parseF…

spring boot 定時任務

package com.ict.conf; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled;Configuration EnableScheduling // 啟用定時任務 …

搬運機器人舉杯賀所需的條件_智能搬運機器人比賽規則

附件4&#xff1a;分揀機器人(智能搬運機器人)比賽規則1、比賽目的設計一個輪式或人形小型機器人&#xff0c;在比賽場地里移動&#xff0c;將不同顏色、形狀或者材質的物體分類搬運到不同的對應位置。比賽的記分根據機器人將物體放置的位置精度和完成時間來決定分值的高低。它…