mysql亂七八糟的可重復(fù)讀隔離級別實(shí)現(xiàn)

mysql的隔離級別并非是按照標(biāo)準(zhǔn)實(shí)現(xiàn)的究恤,作為從pg切過來的程序員還真是不太適應(yīng)袁余,這篇文章討論mysql隔離級別實(shí)現(xiàn)的,希望對大家能有幫助茂嗓。

什么是事務(wù)

事務(wù)是數(shù)據(jù)庫一組讀寫操作的集合钥勋,事務(wù)具有ACID四個特性炬转,原子性,一致性算灸,隔離性和持久性扼劈。
事務(wù)有四個隔離級別,分別是讀未提交菲驴,讀已提交测僵,可重復(fù)讀和串行化。
以上這些內(nèi)容相信熟悉傳統(tǒng)數(shù)據(jù)庫的人谢翎,對這些都很熟悉,接下來講的內(nèi)容可能有些人就不太了解了沐旨。

事務(wù)的實(shí)現(xiàn)方式

數(shù)據(jù)庫事務(wù)的實(shí)現(xiàn)方式主要有兩種:

  1. 基于鎖的森逮;
  2. 基于時間戳的,現(xiàn)在主流的實(shí)現(xiàn)就是基于時間戳的方式的一種磁携,就是大家熟悉的MVCC機(jī)制褒侧;

因?yàn)闄C(jī)制不同,所以事務(wù)的表現(xiàn)也不盡相同谊迄。

不同機(jī)制下的不同隔離級別

SQL標(biāo)準(zhǔn)定義了四種隔離級別闷供,分別是讀未提交,讀已提交统诺,可重復(fù)讀歪脏,可串行化。很明顯粮呢,越低隔離級別的事務(wù)并發(fā)行更好婿失,但是一致性更低钞艇,嚴(yán)格來說,低隔離級別的事務(wù)是不符合A和I的豪硅,常用的隔離級別多為讀已提交和可重復(fù)度哩照。
但是隔離級別的定義是基于鎖并發(fā)控制實(shí)現(xiàn)的,基于MVCC機(jī)制實(shí)現(xiàn)的數(shù)據(jù)庫事務(wù)表現(xiàn)行為會稍有不同懒浮。
jim gray曾經(jīng)有一篇論文討論不同機(jī)制實(shí)現(xiàn)的數(shù)據(jù)庫隔離級別的不同表現(xiàn)飘弧,并將隔離級別擴(kuò)展到7個。見下圖:

七種隔離級別.png

基于此將常見的傳統(tǒng)數(shù)據(jù)庫隔離級別統(tǒng)計如下:

  1. SYBASE支持的隔離級別:degree 0(read uncommitted)砚著、degree 1(read committed)次伶、degree 2(repeatable read)、degree 3(serializable isolation)赖草;
  2. ORACLE支持的隔離級別:read committed(consistent read)学少、serializable(snapshot isolation);
  3. DB2支持的隔離級別:read uncommitted秧骑、cursor stability版确、read stability、repeatable read乎折;
  4. Postgresql支持的隔離級別:read committed(consistent read)绒疗、repeatable read(snapshot isolation)、serializable isolation(Serialaizable Snapshot Isolation)骂澄;
  5. SQL Server支持的隔離級別:read uncommitted吓蘑、read committed snapshot 、read committed 坟冲、repeatable read磨镶、snapshot isolation、serializable isolation健提;
  6. MySQL支持的隔離級別:read uncommitted琳猫、read committed(consistent read)、repeatable read(snapshot isolation)私痹、serializable isolation脐嫂;

幻讀(P3/A3)和寫偏斜(A5B)

上圖的各個字母都是數(shù)據(jù)庫的各種不一致現(xiàn)象。如果把寫操作記作w紊遵,讀操作記作r账千,那么這些有害依賴可以表示為下圖

identifier query phenomena
P0 w1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order) Dirty Write
P1 w1[x]...r2[x]...((c1 or a1) and (c2 or a2) in any order) Dirty Read
P2 r1[x]...w2[x]...((c1 or a1) and (c2 or a2) any order) Fuzzy / Non-Repeatable Read
P3 r1[P]...w2[y in P]...((c1 or a1) and (c2 or a2) any order) Phantom
P4 r1[x]...w2[x]...w1[x]...c1 Lost Update
P4C rc1[x]...w2[x]...w1[x]...c1 Lost Update
A3 r1[P]...w2[y in P]...c2....r1[P]...c1 Phantom
A5A r1[x]...w2[x]...w2[y]...c2...r1[y]...(c1 or a1) Read Skew
A5B r1[x]...r2[y]...w1[y]...w2[x]...(c1 and c2 occur) Write Skew

mysql中的可重復(fù)度

幻讀

mysql是支持MVCC機(jī)制實(shí)現(xiàn)的數(shù)據(jù)庫,因此很多人(包括我)會想當(dāng)然認(rèn)為他的SI應(yīng)該就是標(biāo)準(zhǔn)的實(shí)現(xiàn)暗膜,不會出現(xiàn)幻讀(A3/P3)的現(xiàn)象匀奏。接下來,請看如下例子:

mysql幻讀1-1.jpg

如上圖所示桦山,事務(wù)2的insert發(fā)生在兩次select之間攒射,這兩次select也如SI一樣正確的顯示了該看到的結(jié)果醋旦,但是update發(fā)生之后,一切就變了会放,MySQL的RR隔離級別也會幻讀K瞧搿!咧最!

寫偏斜

也許有人會說捂人,mysql同時也是使用鎖的,因此發(fā)生幻讀不奇怪矢沿,所以我們可以看接下來這個寫偏斜的經(jīng)典例子:

mysql write skew.png

顯然滥搭,mysql也是會發(fā)生寫偏斜的。

mysql中可重復(fù)讀的實(shí)現(xiàn)

看源碼可以發(fā)現(xiàn)捣鲸,mysql中的讀操作是使用MVCC機(jī)制實(shí)現(xiàn)瑟匆,可以正確的查找到需要的行,但是寫操作實(shí)現(xiàn)的時候有兩點(diǎn)和我想的不太一樣:

  1. 寫操作永遠(yuǎn)讀取已提交的數(shù)據(jù)栽惶,并沒有走M(jìn)VCC的邏輯愁溜;
  2. 寫操作的并發(fā)是通過鎖控制的,不檢查更新行是否是對本事務(wù)可見的外厂。

MVCC機(jī)制行的可見條件很簡單冕象,可以總結(jié)為兩句話:

  1. 對不同事務(wù),插入事務(wù)已提交汁蝶,刪除事務(wù)未提交(update可以看做先刪除后插入)渐扮;
  2. 對本事務(wù),插入的statement發(fā)生在自己之前掖棉,刪除的statement未發(fā)生或在自己之后墓律;

套用幻讀那個例子,本來事務(wù)1是不該看到新插入的行的(因?yàn)椴环峡梢姉l件1)幔亥,但是update只讀取最新的行只锻,因此對新插入的行做了一次更新,導(dǎo)致該行符合可見條件2紫谷,再次select就可以查到這個行。

根據(jù)這個實(shí)現(xiàn)捐寥,我們可以推理出笤昨,mysql的可重復(fù)讀同樣會發(fā)生lost update和read skew,只要測試的事務(wù)中存在寫操作握恳。具體例子可見此處

mysql的可重復(fù)讀是比SI更低的隔離級別瞒窒,在發(fā)生幻讀時,SI隔離級別事物的正確行為應(yīng)該是后提交的事務(wù)回滾乡洼,而mysql兩個事務(wù)都可以提交崇裁,顯然匕坯,他的一致性更低,但是并發(fā)性更好(回滾率低)拔稳,這是一次在用戶使用習(xí)慣葛峻,性能和一致性之間的權(quán)衡,至于優(yōu)劣巴比,就見仁見智了术奖,至少現(xiàn)在看來不壞。

postgresql中的可重復(fù)讀

無幻讀

pg實(shí)現(xiàn)的隔離級別是比較標(biāo)準(zhǔn)的轻绞,可重復(fù)度級別(實(shí)際是SI)沒有幻讀采记,這里舉兩個例子

第一個例子
pg無幻讀1.jpg

類比mysql的第一個例子,和mysql不同政勃,可以看到pg的事務(wù)update的時候只更新了兩行唧龄,不包括新插入的行

第二個例子
pg無幻讀2.jpg

當(dāng)該行同時被兩個可重復(fù)級別的事務(wù)更新時,后提交的事務(wù)會回滾奸远,因?yàn)楦轮荒茉谧钚碌男猩蠄?zhí)行既棺,否則就是丟失更新了。

寫偏斜

pg write skew.png

可以看到然走,pg的可重復(fù)級別事務(wù)援制,還是存在寫偏斜的,這是符合標(biāo)準(zhǔn)的芍瑞。

參考文檔

  1. 《A Critique of ANSI SQL Isolation Levels》
  2. mysql源碼
  3. pg源碼
  4. https://github.com/ept/hermitage/blob/master/mysql.md

廣告

最后晨仑,打個廣告,如果對創(chuàng)業(yè)拆檬,分布式數(shù)據(jù)庫和開源社區(qū)感興趣洪己,歡迎加入我們,實(shí)習(xí)和工作都很歡迎竟贯!
pingcap是國內(nèi)為數(shù)不多的newsql方向的分布式數(shù)據(jù)庫答捕,維護(hù)國內(nèi)最頂級的開源社區(qū),關(guān)注度近萬屑那,做類f1+spanner架構(gòu)拱镐,和多家公司有合作關(guān)系。
TiDB: https://github.com/pingcap/tidb
TiKV: https://github.com/pingcap/tikv
Email: xuwentao@pingcap.com
微信: fbisland

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末持际,一起剝皮案震驚了整個濱河市沃琅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜘欲,老刑警劉巖益眉,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡郭脂,警方通過查閱死者的電腦和手機(jī)年碘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來展鸡,“玉大人屿衅,你說我怎么就攤上這事∮榧眨” “怎么了傲诵?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長箱硕。 經(jīng)常有香客問我拴竹,道長,這世上最難降的妖魔是什么剧罩? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任栓拜,我火速辦了婚禮,結(jié)果婚禮上惠昔,老公的妹妹穿的比我還像新娘幕与。我一直安慰自己,他們只是感情好镇防,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布啦鸣。 她就那樣靜靜地躺著,像睡著了一般来氧。 火紅的嫁衣襯著肌膚如雪诫给。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天啦扬,我揣著相機(jī)與錄音中狂,去河邊找鬼。 笑死扑毡,一個胖子當(dāng)著我的面吹牛胃榕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞄摊,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼勋又,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了换帜?” 一聲冷哼從身側(cè)響起赐写,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膜赃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揉忘,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡跳座,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年端铛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疲眷。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡禾蚕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狂丝,到底是詐尸還是另有隱情换淆,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布几颜,位于F島的核電站倍试,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蛋哭。R本人自食惡果不足惜县习,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谆趾。 院中可真熱鬧躁愿,春花似錦、人聲如沸沪蓬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跷叉。三九已至逸雹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間性芬,已是汗流浹背峡眶。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留植锉,地道東北人辫樱。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像俊庇,于是被迫代替她去往敵國和親狮暑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容