InnoDB的隔離級別實現

併發問題,

丟失修改,不可重複讀,幻讀,髒讀

  • 不可重複讀
    有個事務T,T讀了兩次數據,在兩次中間有人update/delete了數據,導致T兩次讀的結果不一致
  • 幻讀
    (在高性能mysql裏把這個歸爲不可重複讀)同上讀了兩次,中間有人insert了一條數據,導致兩次結果不一致
  • 髒讀
    即讀到其他事務未提交的數據
  • 丟失修改
    兩個事務先後讀改再提交,導致最終結果錯誤(?)

事務隔離級別有四種,RU,RC,RR和SI

三段鎖協議

一段鎖:在改前加X鎖,T完釋放,可解決丟失修改(不可以啊?)

二段鎖:讀前S鎖,讀完釋放,解決髒讀

三段鎖,讀前S鎖,T完釋放,解決不可重複讀

以上是理論,實際InnoDB的隔離級別的實現與這些大不相同,


mysql的實現

RC

在RC和RR下都用到了MVCC.

MySQL的讀已提交實際是語句級別快照,即快照讀的時候讀的總是最新的快照.讀的策略與可重複讀類似。

RC寫鎖的使用方式。這裏不需要GAP LOCK,只使用記錄鎖(所以會幻讀)。並且事務只持有被UPDATE/DELETE記錄的寫鎖(可重複讀需要保留全部寫鎖直到事務結束,而讀已提交只保留真正更改的)。

RR

RR下也用MVCC,和RC的區別是它讀的是事務開始時的快照.

RR下默認讀不加鎖而是用快照讀,只有寫才加鎖,讀寫互不阻塞,但會有Write Skew異常(TODO)

RC和RR差別是:RC隔離級別下的事務在每次查詢的開始都會生成一個獨立的ReadView,而可重複讀隔離級別則在第一次讀的時候生成一個ReadView,之後的讀都複用之前的ReadView

在RR下一般下select默認是快照讀,除非用select for update 和select in share lock

  • 其中select in share lock是用行鎖,
  • select for update是用間隙鎖,即next lock算法,
  • 快照讀,能保證read和update操作能並行,即用MVCC存儲每個事務的多個版本,故名字爲多版本控制

如果是快照讀,可重複讀級別下不存在幻讀;如果先用快照讀又用select...from...for update(locking read)讀就存在幻讀;如果兩次查詢都是select...from...for update不會幻讀。

next-key lock

next-key鎖=行鎖+間隙鎖, 來解決幻讀,是謂詞鎖predict lock的改進(?)

還有用previous lock(TODO)

next-key lock會在select for update觸發,鎖定[)左閉右開的旁邊兩個值範圍,左閉右開是因爲自增操作(不是很理解?)

record lock會鎖索引,沒有索引則鎖隱式的主鍵

對於唯一索引,InnoDB會把next-key lock降級爲Record lock

即:若是沒有索引的條件下,就獲取所有行,都加上行鎖,然後Mysql會再次過濾符合條件的的行並釋放鎖,

只有符合條件的行纔會繼續持有鎖。這樣性能也會消耗很大.

MVCC

在多版本存儲上,MySQL採用從新到舊(Newest To Oldest)的版本鏈。

B+Tree葉結點上,始終存儲的是最新的數據(可能是還未提交的數據)。

而舊版本數據,通過UNDO記錄(做DELTA)存儲在回滾段(Rollback Segment)裏。

每一條記錄都會維護一個ROW HEADER元信息,存儲有創建這條記錄的事務ID,一個指向UNDO記錄的指針。通過最新記錄和UNDO信息,可以還原出舊版本的記錄。

用白話文說,每一行數據會有多種版本,而舊版本信息是存在undo log裏的,要用的時候通過對應的undo log來推導出來

 

可串行化(Serializable)

在可串行化級別上,MySQL執行S2PL併發控制協議, 一階段申請,一階段釋放。讀寫都要加鎖。

參考資料

  1. 知乎的MVCC
  2. CNblog的next key lock
  3. undo_log

TODO

  1. next lock算法細則
  2. next key lock會鎖定多大的範圍呢
  3. 間隙鎖和next lock區別,next lock=行鎖+間隙鎖吧
  4. next key lock普通的select都會鎖定這個範圍嗎,RR級別 select不用for update 會用next-key lock嗎
  5. write skew產生的幻讀,知乎的解釋
  6. ReadView是什麼?MVCC和快照的實現,裏面也有undo和readview關係
  7. 數據庫面經
  8. 各種衝突畫時間圖來鞏固下
  9. snapshot(readview)和可見性的判斷
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章