MySQL Innodb的MVCC實現原理

2021-08-21 02:51:26 字數 976 閱讀 3046

mvcc是multi-version concurrency control的縮寫,也就是多版本併發控制。大家都知道,事務的隔離可以通過行鎖來實現。在開啟事務時,對操作記錄加行鎖,事務結束時釋放鎖。但是這樣加鎖會降低事務的併發量,並且對執行緒的阻塞和恢復操作也會損耗效能。那種在事務中使用了select …… for update/ lock in share mode 的就是對記錄使用了行鎖,實現一致性鎖定讀。而對於未加鎖的記錄,在innodb中的repeatable read級別下會通過mvcc進行併發控制,實現一致性非鎖定讀。

一般概念上的mvcc是通過在row record上隱式的增加兩個版本號(建立版本號和刪除版本號)欄位來記錄資料的建立時間和刪除時間。新增記錄時,建立版本號填入當前事務的事務號,刪除版本號置空;刪除記錄時,將記錄標記為刪除狀態,並將當前事務號填入刪除版本號;當進行更新記錄操作時,則是先將舊記錄標記為刪除(並填入刪除版本號),而後在插入一條新的記錄,建立版本號填入當前事務號。這樣在同乙個事務中,不管期間有多少個其它併發事務對其查詢的記錄做過任何操作,都可以通過將查詢出的所有記錄進行版本號過濾(過濾掉建立版本號大於當前事務號和刪除版本號小於當前事務號的記錄),得到與事務開啟時一致的查詢結果。通過mvcc,減少了對資料加鎖的操作,減小效能開銷,大大提高了資料庫的事務併發能力。

mysql中的mvcc雖然從原理上講和上述實現相似,但是實際的實現則略有不同,主要是體現在update操作上。首先,row record上和mvcc相關的隱式字段有3個,data_trx_id,data_roll_ptr,delete bit:

在更新行的時候,先對記錄加鎖,然後把行資料複製乙份到回滾段的undo日誌中,並將data_roll_ptr的指標指向undo中的記錄。然後更新記錄,同時將當前的事務號作為該行的更新版本填入data_trx_id欄位。這樣,當查詢被其它事務修改了的記錄時,可以根據data_roll_ptr 一層一層的回溯到當前事務開啟前的資料版本,實現快照讀。

參考資料:innodb多版本(mvcc)實現簡要分析、mysql中的mvcc

關於 Mysql innodb的索引

關於innodb的索引,可以分為聚簇索引,輔助索引,都是以b tree 為底層資料結構。聚簇索引 只是資料的儲存方法。以主鍵為key,如果表中沒有主鍵,則會選擇乙個有唯一索引的列作為key,如果都沒有,innodb會為我們建立乙個唯一列作為key。所有的資料都存在葉子節點上,並且是按順序儲存的。如果...

MySQL Innodb 索引的原理

回想四年前,我在學習mysql的索引這塊的時候,老師在講索引的時候,是像下面這麼說的 索引就像一本書的目錄。而當使用者通過索引查詢資料時,就好比使用者通過目錄查詢某章節的某個知識點。這樣就幫助使用者有效地提高了查詢速度。所以,使用索引可以有效地提高資料庫系統的整體效能。嗯,這麼說其實也對。但是呢,大...

MySQL InnoDB的體系架構

innodb儲存引擎是乙個完整支援acid事務的mysql儲存引擎,其特點是 行鎖設計,支援mvcc,支援外來鍵,提供一致性非鎖定讀,同時被設計用來最有效的利用以及使用記憶體和cpu 1.innodb體系架構 圖中簡單顯示了innodb的儲存引擎的體系架構,從圖中可見,innodb有多個記憶體塊,可...