InnoDB的MVCC,是通過在每行記錄後面保存三個隱藏的列來實現的其中的兩個列一個保存了行的創建時間,一個保存行的過期時間(或刪除時間)。當然存儲的並不是實際的時間值,而是系統版本號(system version number): 1、DB_TRX_ID :6位元組的事務ID,每處理一個事務,其值自 ...
InnoDB的MVCC,是通過在每行記錄後面保存三個隱藏的列來實現的其中的兩個列一個保存了行的創建時間,一個保存行的過期時間(或刪除時間)。當然存儲的並不是實際的時間值,而是系統版本號(system version number):
1、DB_TRX_ID :6位元組的事務ID,每處理一個事務,其值自動+1,上述說的 “創建時間”和 “刪除時間” 記錄的就是這個DB_TRX_ID值,DB_TRX_ID是最重要的一個,可以通過“show engine innodb status”來查
2、DB_ROLL_PTR:大小時7byte,指向寫到rollback segment(回滾段)的一條undo log記錄(update操作的話,記錄update前的row值)
3、DB_ROLL_ID:大小是6位元組,該值隨新行插入單調增加,當由innodb自動產生聚集索引時,聚集索引包括這個DB_ROW_ID的值,不然的話聚集索引中不包括這個值(我的理解是如果聚集索引不是自動產生的話,就不會有DB_ROLL_ID這個值)。 這個用於索引當中
MVCC只在REPEATABLE READ和READ COMMITTED兩個隔離級別下工作。其他兩個隔離級別都和MVCC不相容。下麵看一下在REPEATABLE READ隔離級別下,MVCC具體是如何操作的
SELECT
-
- InnoDB只查找版本早於當前事務版本的數據行(也就是行的系統版本號必須小於等於事務的版本),這確保當前事務讀取的行都是事務之前已經存在的,或者是由當前事務創建或修改過的。
- 行的刪除操作的版本一定是未定義的或者大於當前事務的版本號。確定了當前事務開始之前,行沒有被刪除
只有符合上述兩點才能返回查詢結果。
INSERT
InnoDB為每個新增行記錄當前系統版本號作為創建ID
DELETE
InnoDB為刪除的每一行保存當前系統版本號作為行刪除標識
UPDATE
InnoDB為插入一行新記錄,保存當前系統版本號作為行版本號,同事保存當前系統版本號到原來的行作為行刪除標識
參考:
[1] 《高性能MySQL》(第三版), Baron Schwartz等 著,寧海元等 譯,電子工業出版社 ,2013
[2] 博客,http://www.cnblogs.com/chenpingzhao/p/5065316.html
[3] 博客,https://www.percona.com/blog/2014/12/17/innodbs-multi-versioning-handling-can-be-achilles-heel/
[4] 博客,http://blogread.cn/it/article/5969
[5] 博客,http://blog.csdn.net/chen77716/article/details/6742128
[6] 博客,http://blog.chinaunix.net/link.php?url=http://forge.mysql.com%2Fwiki%2FMySQL_Internals