mysql mvcc 的理解


mvcc 全稱 multiple version concurrency control 多版本並發控制,是數據庫領域比較常用的一種非鎖並發技術。

mysql 的innodb中,在RR、RC級別會使用mvcc來提升並發。

 

實現原理:

  首先理解幾個基本知識點。

一、mysql在行都設置了默認列(對查詢不可見),包含有 data_trx_id、data_roll_ptr、db_row_id、delete bit

  • db_row_id是在用戶沒設置聚集索引保留
  • delete bit 刪除標志
  • data_trx_id 最近更新或創建 這條記錄的 事務id
  • data_roll_ptr 回滾指針(也稱之為刪除事務id,在事務中查找查找上個版本的記錄就靠這個指針,指向了undo log的地址,可以把同一個事務中的多個版本理解為鏈式關系)

二、Read View:RR、RC級別,開啟事務時,每個事務各自都會維護一份Read View,ReadView 中包含了當前DBMS中活躍的事務id列表(即begin開啟了,但未commit的事務),后續簡稱RV。

三、事務select的檢索的規則:

  1. 查找比當前事務id小的trx_id,這樣能夠保證查詢出當前事務開啟前已經寫入或提交的數據。
  2. 查找行刪除事務Id未設置或者刪除事務Id值大於當前事務Id,這樣能保證,當前事務開啟后被刪除的數據對當前事務是可見的。
  3. 匹配Read View 列表(因為前兩條並能不保證mvcc的正確性,見下文舉例)
    • 比較RV中max(trx_id) 和 min(trx_id) 
      • 如果current_trx_id < min(trx_id) 說明要訪問的版本早已經提交,對當前事務來說數據都是可見的  
      • 如果min<current_trx_id<max 說明當前事務可能正處於活動事務列表中,查找列表如果事務還存在,那么版本不可見從該行的roll_ptr指向的行獲取值,如果不在列表說明事務已經提交了,數據可見。
      • 如果current_trx_id >max 說明當前事務是在RV副本生成之后產生的,更新的數據應該不可見,從該行的roll_ptr指向的行獲取值。

看下具體過程:

當事務級別為默認級別RR時:

假設 有張表

test(bl varchar(20),id not null primary key)

 有事務 A、B、C、D  分兩個場景來看 RV的關系。

場景1:

  RR級別時候,RV不會更新,一直保持開啟事務時候生產的RV,RV=[1]當前數據不可用,需要查詢歷史版本,發現roll_ptr為空,無歷史版本,古返回為空。

  RC級別時候,每次查詢RV會生成新的列表,最終RV為空,故直接返回行數據即可。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

場景2 ,表初始數據是 "小明"
  RR級別時也是一樣,會一直持有同一張RV,RV=[1,2] ,會認為1,2 版本均不可用戶,會尋找1,2版本的歷史版本,返回值是 小明

  RC級別的時候,RV會一直更新,RV=[2]會查找2的歷史版本 trx_id=1的提交記錄,小明1,以此類推。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

能看出來 mysql innoDB實現的並不是純粹的MVCC 模式,其中還加入了X鎖。嚴格來講應該是 “X鎖+MVCC”來達到MVCC的目的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM