1.1 什麼是mvcc
mvcc是一種多版本併發控制機制。
1.2 mvcc是為了解決什麼問題?
1.3 mvcc實現
mvcc是通過儲存資料在某個時間點的快照來實現的. 不同儲存引擎的mvcc. 不同儲存引擎的mvcc實現是不同的,典型的有樂觀併發控制和悲觀併發控制.
下面,我們通過innodb的mvcc實現來分析mvcc使怎樣進行併發控制的.
innodb的mvcc,是通過在每行記錄後面儲存兩個隱藏的列來實現的,這兩個列,分別儲存了這個行的建立時間,乙個儲存的是行的刪除時間。這裡儲存的並不是實際的時間值,而是系統版本號(可以理解為事務的id),沒開始乙個新的事務,系統版本號就會自動遞增,事務開始時刻的系統版本號會作為事務的id.下面看一下在repeatable read隔離級別下,mvcc具體是如何操作的.
create table yang(
id int primary key auto_increment,
name varchar(20));
假設系統的版本號從1開始.
insert
innodb為新插入的每一行儲存當前系統版本號作為版本號.
第乙個事務id為1;
start
transaction;
insert
into yang values(null,'yang') ;
insert
into yang values(null,'long');
insert
into yang values(null,'fei');
commit;
對應在資料中的表如下(後面兩列是隱藏列,我們通過查詢語句並看不到)
idname
建立時間(事務id)
刪除時間(事務id)
1yang
1undefined
2long
1undefined
3fei
1undefined
select
innodb會根據以下兩個條件檢查每行記錄:
a.innodb只會查詢版本早於當前事務版本的資料行(也就是,行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插入或者修改過的.
b.行的刪除版本要麼未定義,要麼大於當前事務版本號,這可以確保事務讀取到的行,在事務開始之前未被刪除.
只有a,b同時滿足的記錄,才能返回作為查詢結果.
delete
innodb會為刪除的每一行儲存當前系統的版本號(事務的id)作為刪除標識.
看下面的具體例子分析:
第二個事務,id為2;
start
transaction;
select * from yang; //(1)
select * from yang; //(2)
commit;
假設1
假設在執行這個事務id為2的過程中,剛執行到(1),這時,有另乙個事務id為3往這個表裡插入了一條資料;
第三個事務id為3;
start
transaction;
insert
into yang values(null,'tian');
commit;
這時表中的資料如下:
idname
建立時間(事務id)
刪除時間(事務id)
1yang
1undefined
2long
1undefined
3fei
1undefined
4tian
3undefined
然後接著執行事務2中的(2),由於id=4的資料的建立時間(事務id為3),執行當前事務的id為2,而innodb只會查詢事務id小於等於當前事務id的資料行,所以id=4的資料行並不會在執行事務2中的(2)被檢索出來,在事務2中的兩條select 語句檢索出來的資料都只會下表:
idname
建立時間(事務id)
刪除時間(事務id)
1yang
1undefined
2long
1undefined
3fei
1undefined
假設2假設在執行這個事務id為2的過程中,剛執行到(1),假設事務執行完事務3後,接著又執行了事務4;
第四個事務:
start
transaction;
delete
from yang where id=1;
commit;
此時資料庫中的表如下:
idname
建立時間(事務id)
刪除時間(事務id)
1yang14
2long
1undefined
3fei
1undefined
4tian
3undefined
接著執行事務id為2的事務(2),根據select 檢索條件可以知道,它會檢索建立時間(建立事務的id)小於當前事務id的行和刪除時間(刪除事務的id)大於當前事務的行,而id=4的行上面已經說過,而id=1的行由於刪除時間(刪除事務的id)大於當前事務的id,所以事務2的(2)select * from yang也會把id=1的資料檢索出來.所以,事務2中的兩條select 語句檢索出來的資料都如下:
idname
建立時間(事務id)
刪除時間(事務id)
1yang14
2long
1undefined
3fei
1undefined
update
innodb執行update,實際上是新插入了一行記錄,並儲存其建立時間為當前事務的id,同時儲存當前事務id到要update的行的刪除時間.
假設3假設在執行完事務2的(1)後又執行,其它使用者執行了事務3,4,這時,又有乙個使用者對這張表執行了update操作:
第5個事務:
start
transaction;
update yang set name='long'
where id=2;
commit;
根據update的更新原則:會生成新的一行,並在原來要修改的列的刪除時間列上新增本事務id,得到表如下:
idname
建立時間(事務id)
刪除時間(事務id)
1yang14
2long15
3fei
1undefined
4tian
3undefined
2long
5undefined
繼續執行事務2的(2),根據select 語句的檢索條件,得到下表:
idname
建立時間(事務id)
刪除時間(事務id)
1yang14
2long15
3fei
1undefined
還是和事務2中(1)select 得到相同的結果.
理解MYSQL MVCC 實現機制
大家都應該知道,鎖機制可以控制併發操作,但是其系統開銷較大,而mvcc可以在大多數情況下代替行級鎖,使用mvcc,能降低其系統開銷.start transaction insert into yang values null,yang insert into yang values null,lon...
輕鬆理解MYSQL MVCC 實現機制
支援原創,大家去看原文吧 1.1 什麼是mvcc mvcc是一種多版本併發控制機制。1.2 mvcc是為了解決什麼問題?1.3 mvcc實現 mvcc是通過儲存資料在某個時間點的快照來實現的.不同儲存引擎的mvcc.不同儲存引擎的mvcc實現是不同的,典型的有樂觀併發控制和悲觀併發控制.下面,我們通...
輕鬆理解MYSQL MVCC 實現機制
大家都應該知道,鎖機制可以控制併發操作,但是其系統開銷較大,而mvcc可以在大多數情況下代替行級鎖,使用mvcc,能降低其系統開銷.start transaction insert into yang values null,yang insert into yang values null,lon...