46
技術社區[雲棲]
MySQL鎖係列(六)之 MVCC
agenda
我們能學到什麼
什麼是MVCC
MVCC能解決什麼問題
MVCC的實現原理
一、什麼是MVCC
- 名詞解釋
英文名:Multi Version Concurrency Control
中文名:多版本一致性控製
- 應用場景
- 大家有沒有這樣的疑問,線上的表一直被更新,可是為什麼還可以去select呢?
- 我的更新事務還沒有提交,為什麼另外一個事務可以讀到數據呢?
- 我的更新事務已經提交,另一個事務又是怎麼選擇數據返回給用戶呢?
二、MVCC能解決什麼問題
- 解決的問題
1. snapshot查詢不會加鎖,讀和讀,讀和寫之間互不影響,提高數據庫的並發能力
2. 隔離級別的實現
三、MVCC的實現原理
3.1 row的記錄格式
記住這個格式,很重要
3.2 row 和 undo
3.3 readview
3.4 可見性判斷
- 實現原理
readview = 活躍事務列表
readview(RR): 事務開始時產生readview
readview(RC): 每條語句都會產生readview
如何判斷可見性:
假設:活躍事務為(3,4,5,6)=readview,當前事務id號為10,做了修改這條記錄 , 那麼這條記錄上的db_trx_id=10
流程如下:
當前事務(trxid=10)拿著剛剛產生的readview =(3[active_trx_min],4,5,6【active_trx_max】)去查看記錄,
1.如果row上的db_trx_id in (活躍事務列表),那麼說明此記錄還未提交,這條記錄對於此事務不可見.需要調用上一個undo,用同樣的判斷標準過濾,循環
2.如果row上的db_trx_id < 活躍事務列表最小值,那麼說明已經提交,這條記錄對於此事務可見
3.如果row上的db_trx_id > 活躍事務列表最大值, 那麼說明該記錄在當前事務之後提交,這條記錄對於此事務不可見.需要調用上一個undo,用同樣的判斷標準過濾,循環
這裏有個問題: 當前事務id更新後,會鎖住該記錄並更新db_trx_id=10,那麼該記錄上的trx_id肯定是<=當前事務id(10)的,那既然這樣,怎麼會產生db_trx_id > 活躍事務列表最大值呢?
原因:因為當前事務不僅僅是讀取這條被鎖住的記錄,可能還需要讀取其他記錄(這些記錄當然可能被其他更靠後的事務id更新了),那麼這時候其他記錄上的db_trx_id>=10就很正常不過了。
創建readview的位置,不是begin的那個位置,而是begin後麵的SQL語句的位置。(換句話說:就是begin的時候不會分配事務id,隻有執行了sql之後才會分配事務id)
如果你想在開啟transaction的時候就產生readview,分配事務id,那麼可以這樣操作:start transaction with consistent snapshot
percona 中可以有這樣的信息,官方沒有: Trx read view will not see trx with id >= 413 , sees < 411
最後更新:2017-06-17 08:32:27