值得收藏,揭秘 MySQL 多版本併發控制實現原理
MySQL 中多版本併發控制(MVCC),是現代資料庫引擎實現中常用的處理讀寫衝突的手段,MVCC 作為 MySQL 高階應用特性,目的在於提高資料庫高併發場景下的吞吐效能。
一、MVCC出現背景是什麼?
髒讀:一個事務讀取到了另外一個事務沒有提交的資料;
不可重複讀:在同一事務中,兩次讀取同一資料,得到內容不同;
幻讀:同一事務中,用同樣的操作讀取兩次,得到的記錄數不相同。
樂觀鎖:
其實現如同它的名字一樣,是假設比較好的情況。每次取資料的時候都認為他人不會對其修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號機制和CAS演算法實現。 悲觀鎖:
悲觀鎖也如同它的名字一樣,總是假設比較壞的情況,每次取資料的時候都認為他人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻塞直到它拿到鎖(共享資源每次只給一個執行緒使用,其它執行緒阻塞,用完後再把資源轉讓給其它執行緒)。
二、什麼是MVCC,它解決了什麼問題?
我們可以透過比較版本號決定資料是否顯示出來(具體的規則後面會介紹到),讀取資料的時候不需要加鎖也可以保證事務的隔離效果。
快照讀:
讀取的是快照資料,不加鎖的簡單的SELECT都屬於快照讀(只是普通的讀操作)。當前讀:
當前讀就是讀取最新資料,而不是歷史版本的資料。加鎖的SELECT,或者對資料進行增刪改都會進行當前讀(包括加鎖的讀取和DML操作)。
三、應用舉例分析
Case2:當我們讀取的時候用了加行鎖,可能會出現死鎖的情況,如下圖所示。
比如當我們讀到 A 有 1000 元的時候,此時 B 開始執行給 A 轉賬。
四、InnoDB如何實現MVCC?
首先獲取事務自己的版本號,也就是事務 ID;
獲取 Read View;
查詢得到的資料,然後與 Read View 中的事務版本號進行比較;
如果不符合 ReadView 規則,就需要從 Undo Log 中獲取歷史快照;
最後返回符合規則的資料。
up_limit_id,活躍的事務中最小的事務 ID;
trx_ids,系統當前正在活躍的事務 ID 集合;
low_limit_id,活躍的事務中最大的事務 ID;
creator_trx_id,建立這個 Read View 的事務 ID。
DB_ROW_ID :
6-byte,記錄操作該資料事務的事務ID;
DB_TRX_ID :
6-byte,當建立表沒有合適的索引作為聚集索引時,會用該隱藏ID建立聚集索引;
DB_ROLL_PTR :
7-byte,回滾指標,指向上一個版本資料在undo log 裡的位置指標;
五、InnoDB是如何解決幻讀的?
我們同時開啟事務 A 和事務 B,先在事務 A 中進行某個條件範圍的查詢,讀取的時候採用排它鎖,在事務 B 中增加一條符合該條件範圍的資料,並進行提交,然後我們在事務 A 中再次查詢該條件範圍的資料,就會發現結果集中多出一個符合條件的資料,這樣就出現了幻讀。
記錄鎖:
針對單個行記錄新增鎖。
間隙鎖(Gap Locking):
可以鎖住一個範圍(索引之間的空隙),但不包括記錄本身。
採用間隙鎖的方式可以防止幻讀情況的產生。
Next-Key 鎖:
鎖住一個範圍,同時鎖定記錄本身,相當於間隙鎖 + 記錄鎖,可以解決幻讀的問題。
六、總結
MVCC 的核心就是 Undo Log+ Read View。
“MV”就是透過 Undo Log 來儲存資料的歷史版本,實現多版本的管理;
“CC”是透過 Read View 來實現管理,透過 Read View 原則來決定資料是否顯示。
同時針對不同的隔離級別,Read View 的生成策略不同,也就實現了不同的隔離級別。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024420/viewspace-2926163/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL的多版本併發控制MVCC的實現惡琿MySqlMVC
- MySQL-16.MVCC(多版本併發控制)MySqlMVC
- MySQL多版本併發控制MVCC的實現示例程式碼介紹MySqlMVC
- 【Mysql】深入理解 MVCC 多版本併發控制MySqlMVC
- MySQL多版本併發控制——MVCC機制分析MySqlMVC
- 一文了解MySQL中的多版本併發控制MySql
- oracle併發與多版本控制Oracle
- MySQL多版本併發控制機制(MVCC)-原始碼淺析MySqlMVC原始碼
- MVCC多版本併發控制器MVC
- mysql併發控制原理知識點MySql
- PostgreSQL中多版本併發控制詳解SQL
- 值得收藏 | 深度剖析 TensorCore 卷積運算元實現原理卷積
- InnoDB學習(五)之MVCC多版本併發控制MVC
- mysql併發控制MySql
- 資料庫事務和MVCC多版本併發控制資料庫MVC
- MySQL的事務機制和鎖(InnoDB引擎、MVCC多版本併發控制技術)MySqlMVC
- 初識多版本併發控制(MVCC)-每週學習分享MVC
- MySQL 到底是如何做到多版本併發的?MySql
- 併發Lock之ReentrantLock實現原理ReentrantLock
- java併發之SynchronousQueue實現原理Java
- Kubernetes 併發控制與資料一致性的實現原理
- Kubernetes併發控制與資料一致性的實現原理
- 雲流送技術原理是什麼,如何實現多併發?
- Java利用Redis實現非同步邏輯多使用者併發控制JavaRedis非同步
- MySQL如何加鎖控制併發MySql
- Nginx 實現高併發的原理分析Nginx
- 併發——深入分析ThreadLocal的實現原理thread
- 使用併發工具實現 RPC 呼叫流量控制RPC
- MySQL派生表合併最佳化的原理和實現MySql
- 《java併發程式設計的藝術》併發底層實現原理Java程式設計
- 用多執行緒,實現併發,TCP執行緒TCP
- 揭秘MySQL的主從同步實現方案MySql主從同步
- Python實戰小案例,值得收藏!Python
- Java ConcurrentHashMap 高併發安全實現原理解析JavaHashMap
- Go高效併發 10 | Context:多執行緒併發控制神器GoContext執行緒
- MySQL MVCC實現原理MySqlMVC
- MySQL——索引實現原理MySql索引
- 資料庫系列:InnoDB下實現高併發控制資料庫