日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

理解MYSQL MVCC 实现机制

發(fā)布時(shí)間:2024/1/17 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 理解MYSQL MVCC 实现机制 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. MVCC簡介

1.1 什么是MVCC

MVCC是一種多版本并發(fā)控制機(jī)制。

1.2 MVCC是為了解決什么問題?

  • 大多數(shù)的MYSQL事務(wù)型存儲(chǔ)引擎,如,InnoDB,Falcon以及PBXT都不使用一種簡單的行鎖機(jī)制.事實(shí)上,他們都和MVCC–多版本并發(fā)控制來一起使用.
  • 大家都應(yīng)該知道,鎖機(jī)制可以控制并發(fā)操作,但是其系統(tǒng)開銷較大,而MVCC可以在大多數(shù)情況下代替行級(jí)鎖,使用MVCC,能降低其系統(tǒng)開銷.

1.3 MVCC實(shí)現(xiàn)

MVCC是通過保存數(shù)據(jù)在某個(gè)時(shí)間點(diǎn)的快照來實(shí)現(xiàn)的. 不同存儲(chǔ)引擎的MVCC. 不同存儲(chǔ)引擎的MVCC實(shí)現(xiàn)是不同的,典型的有樂觀并發(fā)控制和悲觀并發(fā)控制.

2.MVCC 具體實(shí)現(xiàn)分析

下面,我們通過InnoDB的MVCC實(shí)現(xiàn)來分析MVCC使怎樣進(jìn)行并發(fā)控制的.?
InnoDB的MVCC,是通過在每行記錄后面保存兩個(gè)隱藏的列來實(shí)現(xiàn)的,這兩個(gè)列,分別保存了這個(gè)行的創(chuàng)建時(shí)間,一個(gè)保存的是行的刪除時(shí)間。這里存儲(chǔ)的并不是實(shí)際的時(shí)間值,而是系統(tǒng)版本號(hào)(可以理解為事務(wù)的ID),沒開始一個(gè)新的事務(wù),系統(tǒng)版本號(hào)就會(huì)自動(dòng)遞增,事務(wù)開始時(shí)刻的系統(tǒng)版本號(hào)會(huì)作為事務(wù)的ID.下面看一下在REPEATABLE READ隔離級(jí)別下,MVCC具體是如何操作的.

2.1簡單的小例子

create table yang(?
id int primary key auto_increment,?
name varchar(20));

假設(shè)系統(tǒng)的版本號(hào)從1開始.

INSERT

InnoDB為新插入的每一行保存當(dāng)前系統(tǒng)版本號(hào)作為版本號(hào).?
第一個(gè)事務(wù)ID為1;

start transaction; insert into yang values(NULL,'yang') ; insert into yang values(NULL,'long'); insert into yang values(NULL,'fei'); commit;
  • 1
  • 2
  • 3
  • 4
  • 5

對應(yīng)在數(shù)據(jù)中的表如下(后面兩列是隱藏列,我們通過查詢語句并看不到)

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang1undefined
2long1undefined
3fei1undefined

SELECT

InnoDB會(huì)根據(jù)以下兩個(gè)條件檢查每行記錄:?
a.InnoDB只會(huì)查找版本早于當(dāng)前事務(wù)版本的數(shù)據(jù)行(也就是,行的系統(tǒng)版本號(hào)小于或等于事務(wù)的系統(tǒng)版本號(hào)),這樣可以確保事務(wù)讀取的行,要么是在事務(wù)開始前已經(jīng)存在的,要么是事務(wù)自身插入或者修改過的.?
b.行的刪除版本要么未定義,要么大于當(dāng)前事務(wù)版本號(hào),這可以確保事務(wù)讀取到的行,在事務(wù)開始之前未被刪除.?
只有a,b同時(shí)滿足的記錄,才能返回作為查詢結(jié)果.

DELETE

InnoDB會(huì)為刪除的每一行保存當(dāng)前系統(tǒng)的版本號(hào)(事務(wù)的ID)作為刪除標(biāo)識(shí).?
看下面的具體例子分析:?
第二個(gè)事務(wù),ID為2;

start transaction; select * from yang; //(1) select * from yang; //(2) commit;
  • 1
  • 2
  • 3
  • 4

假設(shè)1

假設(shè)在執(zhí)行這個(gè)事務(wù)ID為2的過程中,剛執(zhí)行到(1),這時(shí),有另一個(gè)事務(wù)ID為3往這個(gè)表里插入了一條數(shù)據(jù);?
第三個(gè)事務(wù)ID為3;

start transaction; insert into yang values(NULL,'tian'); commit;
  • 1
  • 2
  • 3

這時(shí)表中的數(shù)據(jù)如下:

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang1undefined
2long1undefined
3fei1undefined
4tian3undefined

然后接著執(zhí)行事務(wù)2中的(2),由于id=4的數(shù)據(jù)的創(chuàng)建時(shí)間(事務(wù)ID為3),執(zhí)行當(dāng)前事務(wù)的ID為2,而InnoDB只會(huì)查找事務(wù)ID小于等于當(dāng)前事務(wù)ID的數(shù)據(jù)行,所以id=4的數(shù)據(jù)行并不會(huì)在執(zhí)行事務(wù)2中的(2)被檢索出來,在事務(wù)2中的兩條select 語句檢索出來的數(shù)據(jù)都只會(huì)下表:

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang1undefined
2long1undefined
3fei1undefined

假設(shè)2

假設(shè)在執(zhí)行這個(gè)事務(wù)ID為2的過程中,剛執(zhí)行到(1),假設(shè)事務(wù)執(zhí)行完事務(wù)3后,接著又執(zhí)行了事務(wù)4;?
第四個(gè)事務(wù):

start transaction; delete from yang where id=1; commit;
  • 1
  • 2
  • 3

此時(shí)數(shù)據(jù)庫中的表如下:

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang14
2long1undefined
3fei1undefined
4tian3undefined

接著執(zhí)行事務(wù)ID為2的事務(wù)(2),根據(jù)SELECT 檢索條件可以知道,它會(huì)檢索創(chuàng)建時(shí)間(創(chuàng)建事務(wù)的ID)小于當(dāng)前事務(wù)ID的行和刪除時(shí)間(刪除事務(wù)的ID)大于當(dāng)前事務(wù)的行,而id=4的行上面已經(jīng)說過,而id=1的行由于刪除時(shí)間(刪除事務(wù)的ID)大于當(dāng)前事務(wù)的ID,所以事務(wù)2的(2)select * from yang也會(huì)把id=1的數(shù)據(jù)檢索出來.所以,事務(wù)2中的兩條select 語句檢索出來的數(shù)據(jù)都如下:

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang14
2long1undefined
3fei1undefined

UPDATE

InnoDB執(zhí)行UPDATE,實(shí)際上是新插入了一行記錄,并保存其創(chuàng)建時(shí)間為當(dāng)前事務(wù)的ID,同時(shí)保存當(dāng)前事務(wù)ID到要UPDATE的行的刪除時(shí)間.

假設(shè)3

假設(shè)在執(zhí)行完事務(wù)2的(1)后又執(zhí)行,其它用戶執(zhí)行了事務(wù)3,4,這時(shí),又有一個(gè)用戶對這張表執(zhí)行了UPDATE操作:?
第5個(gè)事務(wù):

start transaction; update yang set name='Long' where id=2; commit;
  • 1
  • 2
  • 3

根據(jù)update的更新原則:會(huì)生成新的一行,并在原來要修改的列的刪除時(shí)間列上添加本事務(wù)ID,得到表如下:

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang14
2long15
3fei1undefined
4tian3undefined
2Long5undefined

繼續(xù)執(zhí)行事務(wù)2的(2),根據(jù)select 語句的檢索條件,得到下表:

idname創(chuàng)建時(shí)間(事務(wù)ID)刪除時(shí)間(事務(wù)ID)
1yang14
2long15
3fei1undefined

還是和事務(wù)2中(1)select 得到相同的結(jié)果.

總結(jié)

以上是生活随笔為你收集整理的理解MYSQL MVCC 实现机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。