MVCC (多版本併發控制)  part 1

原文鏈接: https://15721.courses.cs.cmu.edu/spring2018/

 

Compare-and-Swap(CAS) 樂觀鎖實現機制

  • 原子操作,認爲某一內存位置M的值應爲V,如果是,則將位置M的值更新爲V’,否則,操作失敗

                           圖1.1 

內存位置M的值爲20,compare value爲20,兩者相等,如圖1,將位置M更新爲30,如圖2

                    圖 1.2

內存位置M的值爲30,compare value爲25,兩者不相等,如圖3,該操作失敗

                     圖 1.3

  • 可以通過intrinsic function call(內部函數調用)完成,無需寫machine code,編譯器知道如何轉化爲instruction

 

Isolation levels(隔離級別)

Serializability(序列化隔離級別):可以忽略併發場景,但並行度過低,性能受限

事務隔離級別控制該事務暴露給其他併發事務的行爲

可能會引起如下現象:髒讀、不可重複讀、幻讀等。

髒讀:事務1 insert一條數據,但未提交,事務2可以select到這條未提交的數據,一旦事務1發生回滾,該條數據則爲髒數據(mysql undo),稱爲髒讀,即讀到爲提交的數據。

不可重複讀:事務1 select某一條數據,得到一個結果,事務2 update該條數據並已提交,事務1此時再去select該條數據,得到的結果和上次select的結果不一致。不可重複讀主要針對update。

幻讀:事務1 select 某一組數據,如select age小於15的數據,得到一組結果,事務2 insert 一條數據,該數據age 小於15,事務1 再次select age小於15的數據,發現多一條記錄。幻讀主要針對insert

 

基本的事務隔離級別如下:

Serializable(序列化):無幻讀、所有讀可重複、無髒讀

Repeatale reads(可重複讀):可能存在幻讀(phantoms)

Read commited(提交讀):可能存在幻讀、不可重複讀

Read uncommited(未提交讀):所有都有可能發生

 

如圖2.1 是主流數據的事務隔離級別:

                    圖 2.1

事務隔離級別基於SQL-92標準,只關注與基於2PL(2階段鎖)的數據庫系統(DBMS),如下兩個級別與2PL無關

 

CURSOR STABILITY:

--DB2 的默認隔離級別,

--cursor(遊標)是一個pointer inside database system of points out whatever data itms a tuple that the query is operating on that moment,I need to access,the cursor will acquire locks with the things that wants to access,即如果需要掃描2個tuples時,遊標會找到第一個tuple,並對其加鎖,然後做操作,做完操作後釋放該鎖,然後再去獲取第二個tuple的遊標鎖,然後做操作,然後釋放該鎖)

--對於2PL在growing phase獲取所有鎖,如果釋放一個鎖,進入shrinking phase,you can never go back and acquire another lock,but in cursor locking you can do that,由於only one query can hold one cursor at a time,所以不用擔心死鎖

--介於讀提交和可重複讀之間,強於讀提交是因爲可以防止update丟失現象

--可以防止update丟失現象(but not laways)

--update 丟失:如圖2.2

假設在一個單core系統中,txn1 read(A)獲取遊標鎖並釋放,txn2 write(A) 獲取遊標鎖並釋放,txn1 write(A) 獲取遊標鎖並釋放,txn1 commit,稍後txn2 commit。雖然txn2 commit比txn1晚,但是隻能看到txn1 write(A),而txn2 write(A) 被txn1 重寫了,所以txn2 的update似乎丟失了

如果txn1知道將會write(A),就會一直hold the cursor lock,txn2會阻塞,txn1 先提交,然後txn2 執行,就不會出現update丟失的現象。

所以CURSOR STABILITY可以防止update丟失現象,but not always。

 

              圖 2.2  update丟失

 

SNAPSHOT ISOLATION(快照隔離級別):

--參考tidb/cockroachDB,tidb默認級別爲SI,cockroachDB支持SI/SSI兩種級別

--保證事務中所有的read,可以查看到事務開始時,數據庫存在的一致性快照,可以理解爲對每個事務start_timestamp做一致性快照,該快照應用於該事務的所有read

--since that snapshot,事務只有在write與其他的併發update無衝突時才能提交

--易受寫偏序(write skew)現象影響

--寫偏序:如圖2.3

假如txn1想把白塊變成黑塊,txn2想把黑塊變成白塊,當txn1和txn2併發時,他們事務開始時拿到的一致性快照都是上半黑下半白,當txn1和txn2 commit後,變成了上半白下半黑。

但是如果兩個事務序列化執行,得到的操作,應該是txn1先把白的變成黑的,txn2再把黑的變成白的。最後的結果是全白。即由於兩者各自拿到了一致性快照,因爲無法知曉其他事務的修改,提交時又不衝突,而造成的最終結果不一致。

                  圖2.3 寫偏序

幾種事務隔離級別的關係

            圖2.4 幾種事務隔離級別的關係

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章