關於mvcc的探索與研究
之前沒有仔細研究過mysql的mvcc的具體實現,網上的大多數資料都是在講readview在當前讀和快照讀的情況下,mysql讀取的規則與邏輯,只講了在乙個是事務中,mysql如何實現可重複讀的
沒有說明mysql在併發事務中,更新時,會如何處理併發的資料,並且最後怎麼樣保證資料都能得到正確的更新
我自己寫了乙個demo,研究測試了下,具體流程如下:
模擬併發測試mvvc場景執行sql如下:
有表test0105 ,有欄位id,c ,c=1
事務a sql:
set @@autocommit=0;
select @@tx_isolation;
start transaction ;
select * from test0105 where id ='1';-- 1
select sleep(2);
select * from test0105 where id ='1'; -- 1
update test0105 set c=c+1 where id ='1';-- 2
select * from test0105 where id ='1'; -- 2
select sleep(4);
select * from test0105 where id ='1'; -- 2
commit;
select * from test0105 where id ='1'; -- 2
事務b sql:
set @@autocommit=0;
select @@tx_isolation;
start transaction ;
select c from test0105 where id ='1';-- 1
select sleep(2);
select * from test0105 where id ='1'; -- 1
update test0105 set c=c+2 where id ='1';
select * from test0105 where id ='1'; -- 4
select sleep(4);
select * from test0105 where id ='1'; -- 4
commit;
邏輯圖c=1
事務a事務b
開啟事務
開啟事務
快照讀:c=1
更新記錄為+1
快照讀:c=2
執行快照讀:c=1
更新記錄 +2
執行快照讀:c=4
執行快照讀:c=2
提交事務
執行快照讀:c=2
執行快照讀:c=4
提交事務
執行快照讀:c=4
最後結果
c=4結論如下:
在可重複讀隔離級別下進行:
1.事務a進行更新欄位c,會在undolog中,先增加排他鎖,然後複製一行資料,作為roll back資料,然後將新的記錄指向 舊的記錄
2.事務b在事務a提交之前開啟事務,此時繼續做更新操作,也會在indolog 中 先增加排他鎖,然後複製一行資料,作為roll back資料,然後將新的記錄 指向 舊的記錄
3.因為更新操作屬於當前讀,所以查到的是最新的資料,此時如果事務a在事務b 之前完成了更新操作,那麼undolog中的鏈條記錄如下
鏈條頂部 最新的記錄 c=4
b生成的歷史記錄 c=2
a生成的歷史記錄 c=1
為什麼在事務b更新後c會等於4,因為事務b進行的更新操作,屬於當前讀,會從undolog 頂部 獲取最新的記錄,此時為c=2,所以會在記錄上增加2,此時即使沒有提交事務a,也能讀取到最新的記錄 (我感覺是這個原因,或許是其他的= =)
最後事務a提交時 ,c=2 這是因為此時事務a讀取的仍然是當前事務中的快照讀,不會獲取其他事務的快照讀
最後事務b 提交時,c=4 因為事務b後於事務a提交,此時的值是最新的,就是4,此處可能是readview 的判斷機制被重新觸發了,不再讀取第一次獲取的快照讀了
mysql 關於innodb中MVCC的一些理解
mvcc multiversion concurrency control 即多版本併發控制技術,它使得大部分支援行鎖的事務引擎,不再單純的使用行鎖來進行資料庫的併發控制,取而代之的是把資料庫的行鎖與行的多個版本結合起來,只需要很小的開銷,就可以實現非鎖定讀,從而大大提高資料庫系統的併發效能 讀鎖 ...
mysql 關於innodb中MVCC的一些理解
mvcc multiversion concurrency control 即多版本併發控制技術,它使得大部分支援行鎖的事務引擎,不再單純的使用行鎖來進行資料庫的併發控制,取而代之的是把資料庫的行鎖與行的多個版本結合起來,只需要很小的開銷,就可以實現非鎖定讀,從而大大提高資料庫系統的併發效能 讀鎖 ...
mysql中的mvcc解讀
對於mvcc想必大家也看到了不少原始碼層的解讀,最大特點就是分析的是比較深入了,但是卻不大好理解,最後有種不明覺厲的感覺,以至於在面試中經常翻船。我們換個角度來解讀一下,在表設計中,我們有一種策略,那就是盡可能保留資料變化的 歷史,比如在資料發生變化時我們不會直接刪除資料,而是把它轉換為兩類操作。比...