MVCC-多版本併發控制
阿新 • • 發佈:2022-03-30
- 理解快照讀和當前讀
- 快照讀:一致性不加鎖的讀,在可重複讀的隔離級別下,每次事務啟動之前都會對當前庫拍一個快照,當前事務讀取的資料要麼是事務開啟時快照的資料,要麼是事務本身插入或更新的資料;
- 當前讀:當前最新的資料,開啟後能在事務中讀取到其他已提交事務的最新資料;如for update, lock in share model;
for update 與 lock in share model 兩者區別:
for update用於給符合條件的rows加上IX(意向排它鎖),加鎖後,其他事物不能讀取或修改當前被鎖定的rows,但innodb存在一致性非鎖定的讀,所以能讀取對應的快照讀,所以不會阻塞其他事務對鎖定rows的快照度;
lock in share model用於給符合條件的rows加上IS(意向共享鎖)。加鎖後,其他事物能讀取對應的rows,也能給對應的rows加IS鎖,但是無法修改當前鎖定的rows,直到鎖定的session已經提交;
- InnoDB中MVCC:
InnoDB中MVCC是通過兩個隱藏列來實現的,用於儲存行的建立時間和過期時間(刪除時間);這裡所謂的時間不是實際的時間值,而是系統版本號(system version number)。當session開啟時,系統版本號都會自動遞增,作為當前session的版本號,用來和查詢到到每行記錄到版本做比較。
在可重複度隔離級別下,MVCC操作如下:
- SELECT:只查詢版本早於或等於當前事務版本的資料行,行的刪除版本要麼未定義,要麼大於當前事務版本號;
- INSERT:將當前系統版本號作為插入的每一行的版本號;
- UPDATE:儲存當前版本號為行版本號,同時儲存當前版本號到原來的行作為刪除標識;
- DELETE:為刪除的每一行儲存當前系統版本號作為行刪除標識;
MCVV只在讀已提交和可重複度隔離級別下工作,因為讀未提交下總是讀取到最新到資料,不滿足當前事務版本的資料行,而序列化會給每一讀取到的行加鎖。