mvcc 怎麼實現的
1 從乙個實驗講起
在說 mvcc(multi-version concurrency control,多版本併發控制)原理之前,先一起看看乙個例子。
建立一張測試表並寫入測試資料:
進行實驗:
create database likecolumn;
use likecolumn;
create tablet1
(
id
int(11) not null auto_increment,
a
int(11) not null,
b
int(11) not null,
primary key (id
),
keyidx_c
(a
)
) engine=innodb charset=utf8mb4;
insert into t1(a,b) values (1,1),(2,2);
序號session1
session2
1set session transaction_isolation=『readcommitted』;/* 設定會話隔離級別為 rc*/
set session transaction_isolation=『readcommitted』;/* 設定會話隔離級別為 rc*/
這裡解釋一下上面的實驗過程,在 session1 開啟乙個事務更新了 a=1 這行記錄,但還沒提交的情況下,在 session2 中,滿足 a=1 這條記錄,b 的值還是原始值 1,而不是 session1 更新之後的 666,那麼在資料庫層面,這是怎麼實現的呢?
其實 innodb 就是通過 mvcc 和 undo log 來實現的。
2 什麼是 mvcc
mvcc, 即多版本併發控制。mvcc 的實現,是通過儲存資料在某個時間點的快照來實現的。根據事務開始的時間不同,每個事務對同一張表,同一時刻看到的資料可能是不一樣的。
也就是上面實驗第 6 步中,為什麼 session2 查詢的結果還是 session1 修改之前的記錄。
3 mvcc 的實現原理
對於 innodb ,聚簇索引記錄中包含 3 個隱藏的列:
row id:隱藏的自增 id,如果表沒有主鍵,innodb 會自動按 row id 產生乙個聚集索引樹。
事務 id:記錄最後一次修改該記錄的事務 id。
我們拿上面的例子,對應解釋下 mvcc 的實現原理,如下圖:
如圖,首先 insert 語句向表 t1 中插入了一條資料,a 欄位為 1,b 欄位為 1, row id 也為 1 ,事務 id 假設為 1,回滾指標假設為 null。當執行 update t1 set b=666 where a=1 時,大致步驟如下:
資料庫會先對滿足 a=1 的行加排他鎖;
然後將原記錄複製到 undo 表空間中;
修改 b 欄位的值為 666,修改事務 id 為 2;
並通過隱藏的回滾指標指向 undo log 中的歷史記錄;
事務提交,釋放前面對滿足 a=1 的行所加的排他鎖。
在前面實驗的第 6 步中,session2 查詢的結果是 session1 修改之前的記錄,這個記錄就是來自 undolog 中。
因此可以總結出 mvcc 實現的原理大致是:
innodb 每一行資料都有乙個隱藏的回滾指標,用於指向該行修改前的最後乙個歷史版本,這個歷史版本存放在 undo log 中。如果要執行更新操作,會將原記錄放入 undo log 中,並通過隱藏的回滾指標指向 undo log 中的原記錄。其它事務此時需要查詢時,就是查詢 undo log 中這行資料的最後乙個歷史版本。
mvcc 最大的好處是讀不加鎖,讀寫不衝突,極大地增加了 mysql 的併發性。通過 mvcc,保證了事務 acid 中的 i(隔離性)特性
MVCC實現過程
參考 解決問題 髒讀 不可重複讀,因此一般用於rc和rr級別。重點 1 每行新增兩個隱藏字段,乙個表示最近更新此記錄的事務id,稱 data trx id,乙個表示該行的回滾段,稱 data roll ptr。事務id為int型別,回滾段為指標型別,它指向undo log中的記錄。2 undo lo...
MySQL Innodb的MVCC實現原理
mvcc是multi version concurrency control的縮寫,也就是多版本併發控制。大家都知道,事務的隔離可以通過行鎖來實現。在開啟事務時,對操作記錄加行鎖,事務結束時釋放鎖。但是這樣加鎖會降低事務的併發量,並且對執行緒的阻塞和恢復操作也會損耗效能。那種在事務中使用了selec...
Mysql 的 MVCC 實現原理
mysql 中mvcc 實現原理,可翻看原始碼檢視 1個6byte的 db trx id標識 該行insert或者update操作的最新事務id,刪除操作也被當作乙個update操 作 用1個bit表示刪除 1個7byte的db roll ptr,指向寫到rollback segment的一條und...