什么是MVCC,為什么要設(shè)計(jì)間隙鎖?

本篇文章帶大家了解一下mvcc,介紹一下mvcc與隔離級別的關(guān)系,從設(shè)計(jì)的角度上,聊聊為什么要設(shè)計(jì)出mvcc,且rc和rr的隔離級別到底有什么不同。

MVCC作用

MVCC使得大部分支持行鎖的事務(wù)引擎,不再單純的使用行鎖來進(jìn)行數(shù)據(jù)庫的并發(fā)控制,而是把數(shù)據(jù)庫的行鎖和行的版本號結(jié)合起來,只需要很小的開銷,就可以實(shí)現(xiàn)非鎖定讀。從而提高數(shù)據(jù)庫的并發(fā)性能。

MVCC是采用無鎖的形式解決讀-寫沖突問題。這里的讀是指的快照讀。即MVCC實(shí)現(xiàn)的快照讀?。?!

什么是MVCC

多版本并發(fā)控制(MVCC)是一種解決讀-寫沖突的無鎖并發(fā)控制。

每一行記錄都有兩個(gè)隱藏列:創(chuàng)建版本號和回滾指針。事務(wù)開啟后存在一個(gè)事務(wù)id。多個(gè)并發(fā)事務(wù)同時(shí)操作某行,不同的事務(wù)對該行update操作會產(chǎn)生多個(gè)版本,然后通過回滾指針組成undo log鏈。而MVCC的快照讀正是通過事務(wù)id和創(chuàng)建版本號從而實(shí)現(xiàn)的快照讀。

MVCC與隔離級別的關(guān)系

MVCC是為了解決讀-寫問題。且通過不同的配置,也可以解決事務(wù)開啟后,快照讀不可重復(fù)讀的問題。

  • 不可重復(fù)讀:同一個(gè)事務(wù)中讀取某些數(shù)據(jù)已經(jīng)發(fā)生改變,或某些記錄已經(jīng)刪除。

  • 幻讀:一個(gè)事務(wù)按照相同的查詢條件重新讀取以前檢索過的數(shù)據(jù),卻發(fā)現(xiàn)其他事務(wù)插入了滿足查詢條件的新數(shù)據(jù),這種現(xiàn)象被稱為幻讀。

RC和RR均實(shí)現(xiàn)了MVCC,但是為什么RR解決了RC不可重復(fù)讀的問題?

你可以這樣認(rèn)為,RC之所以有不可重復(fù)讀的問題,只是因?yàn)殚_發(fā)者有意設(shè)置的(設(shè)置多種隔離級別,用戶可以根據(jù)情況設(shè)置)。本來數(shù)據(jù)都提交到數(shù)據(jù)庫了,RC讀取出來也沒什么問題呀?況且Oracle數(shù)據(jù)庫本身的隔離級別就是RC。

READ-COMMITTED(讀已提交)
讀已提交RC,在這一隔離級別下,可以在SQL級別做到一致性讀,每次SQL語句都會產(chǎn)生新的ReadView。這就意味著兩次查詢之間有別的事務(wù)提交了,是可以讀到不一致的數(shù)據(jù)的。

REPEATABLE-READ(可重復(fù)讀)
可重復(fù)讀RR,在第一次創(chuàng)建ReadView后,這個(gè)ReadView就會一直維持到事務(wù)結(jié)束,也就是說,在事務(wù)執(zhí)行期間可見性不會發(fā)生變化,從而實(shí)現(xiàn)了事務(wù)內(nèi)的可重復(fù)讀。

MVCC和間隙鎖

MVCC無鎖解決了讀-寫沖突的問題。并且解決了不可重復(fù)讀問題。從而實(shí)現(xiàn)了RC和RR兩個(gè)隔離級別。

間隙鎖本質(zhì)上依舊是鎖,會阻塞兩個(gè)并發(fā)事務(wù)的執(zhí)行。

那么RR為什么還要進(jìn)入間隙鎖,難道僅僅為了解決幻讀的問題嗎?

注意:只有RR隔離級別才存在間隙鎖。

間隙鎖在一定程度上可以解決幻讀的問題,但是間隙鎖的引入我覺得更多是為了處理binlog的statement模式的bug。

mysql數(shù)據(jù)庫的主從復(fù)制依靠的是binlog。而在mysql5.0之前,binlog模式只有statement格式。這種模式的特點(diǎn):binlog的記錄順序是按照數(shù)據(jù)庫事務(wù)commit順序?yàn)轫樞虻摹?/p>

當(dāng)不存在間隙鎖的情況下,會有如下的場景:
master庫有這么兩個(gè)事務(wù):

1、事務(wù)a先delete id2、事務(wù)b直接insert id=3,并且完成commit;
3、事務(wù)a進(jìn)行commit;
此時(shí)binlog記錄的日志是:事務(wù)b先執(zhí)行,事務(wù)a在執(zhí)行(binlog記錄的是commit順序)

那么主庫此時(shí)表里面有id=3的記錄,但是從庫是先插入再刪除,從庫里面是沒有記錄的。

這就導(dǎo)致了主從數(shù)據(jù)不一致。

為了解決這個(gè)bug,所以RR級別引入了間隙鎖。

【相關(guān)推薦:mysql視頻教程

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊12 分享