1. 程式人生 > >我理解的MVCC內部實現原理

我理解的MVCC內部實現原理

  MySQL InnoDB儲存引擎,實現的是基於多版本的併發控制協議——MVCC (Multi-Version Concurrency Control) (注:與MVCC相對的,是基於鎖的併發控制,Lock-Based Concurrency Control)。MVCC最大的好處,相信也是耳熟能詳:讀不加鎖,讀寫不衝突。在讀多寫少的OLTP應用中,讀寫不衝突是非常重要的,極大的增加了系統的併發效能,這也是為什麼現階段,幾乎所有的RDBMS,都支援了MVCC。

  對於delete操作,innodb是通過先將要刪除的那一行標記為刪除,而不是馬上清除這一行,因為innodb實現了MVCC,這些undo段用來實現MVCC多版本機制。鎖不阻塞讀,讀也不阻塞寫,這樣大大提高了併發性。那麼在一致性讀的時候,怎麼才能找到和事務開始的那個版本呢?

	主鍵索引,每個行都有一個事務ID和一個undo ID,這個undo ID指向了這行的先前版本的位置。
	非主鍵索引(輔助索引secondary index),通過先找主鍵索引再找到undo段。而對於update操作,則是先標記刪除,然後insert一個新的行,接下來如果有一致性讀,那麼查詢old version的行的原理和delete操作是一樣的

  innoDB的行記錄格式中有6位元組事務ID的和7位元組的回滾指標,通過為每一行記錄新增這兩個額外的隱藏值來實現MVCC,這兩個值一個記錄這行資料何時被建立,另外一個記錄這行資料何時過期(或者被刪除)。但是InnoDB並不儲存這些事件發生時的實際時間,相反它只儲存這些事件發生時的系統版本號。這是一個隨著事務的建立而不斷增長的數字。每個事務在事務開始時會記錄它自己的系統版本號。每個查詢必須去檢查每行資料的版本號與事務的版本號是否相同。讓我們來看看當隔離級別是REPEATABLE READ時這種策略是如何應用到特定的操作的。

 * SELECT:
當隔離級別是REPEATABLE READ時select操作,InnoDB必須每行資料來保證它符合兩個條件:
1、InnoDB必須找到一個行的版本,它至少要和事務的版本一樣老(也即它的版本號不大於事務的版本號)。這保證了不管是事務開始之前,或者事務建立時,或者修改了這行資料的時候,這行資料是存在的。
2、這行資料的刪除版本必須是未定義的或者比事務版本要大。這可以保證在事務開始之前這行資料沒有被刪除。
符合這兩個條件的行可能會被當作查詢結果而返回。
* INSERT:
InnoDB為這個新行記錄當前的系統版本號。 * DELETE:
InnoDB將當前的系統版本號設定為這一行的刪除ID。 * UPDATE:
InnoDB會寫一個這行資料的新拷貝,這個拷貝的版本為當前的系統版本號。它同時也會將這個版本號寫到舊行的刪除版本里。 這種額外的記錄所帶來的結果就是對於大多數查詢來說根本就不需要獲得一個鎖。他們只是簡單地以最快的速度來讀取資料,確保只選擇符合條件的行。這個方案的缺點在於儲存引擎必須為每一行儲存更多的資料,
做更多的檢查工作,處理更多的善後操作。 MVCC只工作在REPEATABLE READ和READ COMMITED隔離級別下。READ UNCOMMITED不是MVCC相容的,因為查詢不能找到適合他們事務版本的行版本;它們每次都只能讀到最新的版本。
SERIABLABLE也不與MVCC相容,因為讀操作會鎖定他們返回的每一行資料。

併發控制技術:

LBCC:Lock-Based Concurrency Control,基於鎖的併發控制。
MVCC:Multi-Version Concurrency Control,基於多版本的併發控制協議。純粹基於鎖的併發機制併發量低,MVCC是在基於鎖的併發控制上的改進,主要是在讀操作上提高了併發量。
在MVCC併發控制中,讀操作可以分成兩類:
1)快照讀 (snapshot read):讀取的是記錄的可見版本 (有可能是歷史版本),不用加鎖(共享讀鎖s鎖也不加,所以不會阻塞其他事務的寫)。
2)當前讀 (current read):讀取的是記錄的最新版本,並且,當前讀返回的記錄,都會加上鎖,保證其他事務不會再併發修改這條記錄。

相關推薦

理解MVCC內部實現原理

  MySQL InnoDB儲存引擎,實現的是基於多版本的併發控制協議——MVCC (Multi-Version Concurrency Control) (注:與MVCC相對的,是基於鎖的併發控制,Lock-Based Concurrency Control)。MVCC最大的好處,相信也是耳熟能詳:讀不加鎖

@Autowired內部實現原理

dao boolean ice fields ann 打印 sys ava sta @Autowiredprivate CustomerDao customerDao; public void addCustomer() { customerDa

深入理解Git的實現原理

原文地址:https://www.cnblogs.com/mamingqian/p/9711975.html 0、導讀   本文適合對git有過接觸,但知其然不知其所以然的小夥伴,也適合想要學習git的初學者,通過這篇文章,能讓大家對git有豁然開朗的感覺。在寫作過程中,我力求

HashMap內部實現原理

   HashMap的底層是基於陣列+連結的一個複合資料結構,非同步的 允許null鍵值 繼承於map介面來實現,通過put和get方法來進行資料的操作.陣列被分為一個個的bucket.雜湊值決定了鍵值對在陣列中的位置.具有相同雜湊值的鍵值對會組成連結串列,當連結串列長度超過

一篇文章通透理解序列號實現原理

                     1.序列號的本質序列號等價於註冊碼,是軟體發行商的一種維權手段,也就是正版軟體的一個身份證。本質:防止盜版、按功能收費等。 目前,商用軟體和共享軟體絕大部份都是採用註冊碼授權的方式來保證軟體本身不被盜用,以保證自身的利益。儘管很多常用的許多軟體系統的某些版本已經被別人

深入理解 Dijkstra 演算法實現原理

迪傑斯特拉(Dijkstra)演算法 1典型最短路徑演算法,用於計算一個節點到其他節點的最短路徑。 2特點是以起始點為中心向外層層擴充套件(廣度優先搜尋思想),直到擴充套件到終點為止。 大概就是這樣一個有權圖,Dijkstra演算法可以計算任意節點到其他節點的最短

JAVA中的集合原始碼分析一:ArrayList的內部實現原理

作為以java為語言開發的android開發者,集合幾乎天天都要打交道,無論是使用頻率最高的ArrayList還是HashSet,都頻繁的出現在平時的工作中。但是其中的原理之前卻一直沒深入探究,接下來記錄一下這次自己學習ArrayList原始碼的過程。 一.構造方法:

從原始碼的角度來談一談HashMap的內部實現原理

HashMap可以說是我們一個熟悉又陌生的Java中常用的儲存資料的API。說他熟悉,是因為我們經常使用他,而說他陌生是因為我們大部分時間是隻知道他的使用,而並不知道他內部的原理,但是在面試考察的時候又最喜歡去問這個原理。今天,我就來從原始碼的角度,談談對HashMap的理解

深入Java 1.5列舉型別的內部實現原理

Java是一種面向物件的高階程式語言。它的出眾之處就在於它的簡潔。一個程式設計師所要做的就是建立類(Create Class)以及定義介面(Define Interface),如此而已。當然,這種簡潔和優美是有代價的,比如失去了Enum這種廣泛使用的資料型別就是一個不小的損

Android Bundle App內部實現原理

core中的程式碼 首先我們在程式碼中呼叫了 manager = SplitInstallManagerFactory.create(this) 1.SplitInstallManagerFactory.class public class SplitIn

IOS SDWebImage內部實現原理

想必大家都很熟悉SDWebImage了,專案中也經常用。可大家知道它的實現原理嗎?今天就跟大家分享一下。 先看一下下面這幅圖: 圖片解釋:記憶體層面的相當是個快取器,以Key-Value的形式儲存圖片。當記憶體不夠的時候會清除所有快取圖片。用搜索檔案系統

Fresco圖片框架內部實現原理探索

流行的網路框架 目前流行的網路圖片框架:  Picasso、Universal Image Loader、Volley的(ImageLoader、NetworkImageView)、Glide和Fresco 簡明的介紹下(具體細節和功能可

C++ vector的內部實現原理及基本用法

本文基於STL vector原始碼,但是不考慮分配器allocator,迭代器iterator,異常處理try/catch等內容,同時對_Ucopy()、 _Umove()、 _Ufill()函式也不會過度分析。一、vector的定義template<class _Ty

個人對rand()、srand()函式之間的關係及其內部實現原理的猜測

歡迎轉載,轉載請註明出處,謝謝 //首先我們先只看rand()函式,有函式如: int main(int argc,char* argv[]) { int tmp=0; for(int i=0;i<50;++i) { // 獲取 0~19 的偽隨機數,存入t

Go 定時器內部實現原理剖析

前言 前面我們介紹了一次性定時器Timer和週期性定時器Ticker,這兩種定時器內部實現機制相同。建立定時器的協程並不負責計時,

Flask原始碼分析二:路由內部實現原理

前言 Flask是目前為止我最喜歡的一個Python Web框架了,為了更好的掌握其內部實現機制,這兩天準備學習下Flask的原始碼,將由淺入深跟大家分享下,其中Flask版本為1.1.1。 上次瞭解了Flask服務的啟動流程,今天我們來看下路由的內部實現機理。 Flask系列文章: Flask開發初探 F

自定義RPC的完整實現---深入理解rpc內部原理

channel struct seek raise services utf-8 proto encode res 倘若不使用RPC遠端調用的情況下,代碼如下: local.py # coding:utf-8 # 本地調用除法運算的形式 class InvalidOper

通過實現網站訪問計數器帶你理解 輕量級鎖CAS原理,還學不會算輸!!!

一、實現網站訪問計數器 1、執行緒不安全的做法 1.1、程式碼 package com.chentongwei.concurrency; import static java.lang.Thread.sleep; /** * @Description: * @Project concurrency

理解殺進程的實現原理(轉)

dir nullptr signed end 細節 信號signal tar res ets 基於Android 6.0的源碼剖析, 分析kill進程的實現原理,以及講講系統調用(syscall)過程,涉及源碼: /framework/base/core/java/a

8. 理解ZooKeeper的內部工作原理

zab 階段 身份驗證 過多 管理系統 多個 基礎 des jpg 到目前為止,我們已經討論了ZooKeeper服務的基礎知識,並詳細了解了數據模型及其屬性。 我們也熟悉了ZooKeeper 監視(watch)的概念,監視就是在ZooKeeper命名空間中的znode發生任