MySQL中對MVCC的理解
一、MVCC簡介
MVCC (Multiversion Concurrency Control),即多版本併發控制技術。MVCC是通過儲存資料在某個時間點的快照來實現的。不同儲存引擎的MVCC實現是不同的,典型的有樂觀併發控制和悲觀併發控制.
二、MVCC原理
在SQL/">MySQL中每行row中的結構如下:
其中F1~F6表示欄位資訊,後面的DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR和DELETE BIT 為記錄的隱藏欄位,Innodb為每行記錄都對其中這幾個欄位進行了隱藏。
這幾項介紹如下:
- DB_ROW_ID: 長度6個位元組。此值當由InnoDB自動生成,聚集索引時使用。如果使用者未顯式指定表主鍵時,表使用DB_ROW_ID的值作為主鍵ID,聚集索引會使用此值。如果指定了表主鍵的話,則聚集索引使用指定的值。
- DB_TRX_ID: 6個位元組的事務ID。標記了最後更新此記錄的事務ID,每開起一個新事務,其值自動+1
- DB_ROLL_PTR: 7位元組的 回滾指標 。指向當前記錄項的undo log記錄,找之前版本的資料需通過此指標。
- DELETE BIT: 位用於 標識 該記錄是否被刪除,並不是真正的刪除。
下面分別以select、delete、 insert、 update語句來說明
SELECT
Innodb檢查每行資料,確保他們符合兩個標準:
1、InnoDB只查詢版本早於當前事務版本的資料行(也就是資料行的版本必須小於等於事務的版本),這確保當前事務讀取的行都是事務之前已經存在的,或者是由當前事務建立或修改的行。
2、行的刪除操作的版本一定是未定義的或者大於當前事務的版本號,確定了當前事務開始之前,行沒有被刪除。
只有全部符合以上兩種條件的記錄才會返回。
INSERT
InnoDB為每個新增行記錄當前系統版本號作為建立ID。
DELETE
InnoDB為每個刪除行的記錄當前系統版本號作為行的刪除ID。
UPDATE
InnoDB複製了一行。這個新行的版本號使用了系統版本號。它也把系統版本號作為了刪除行的版本。
說明
insert操作時 “建立時間”=DB_ROW_ID,這時,“刪除時間 ”是未定義的;
update時,複製新增行的“建立時間”=DB_ROW_ID,刪除時間未定義,舊資料行“建立時間”不變,刪除時間=該事務的DB_ROW_ID;
delete操作,相應資料行的“建立時間”不變,刪除時間=該事務的DB_ROW_ID;
select操作對兩者都不修改,只讀相應的資料