淺談 Mysql 事務 由 ACID 到 MVCC

最近公司的技術分享一直在分享 mysql 事務,隔離級別,鎖和 MVCC 方面的知識,但是都是基於單個點進行分析,沒有一步一步來闡述,所以在這裏我整理了一下 mysql 由 ACID 到 MVCC 這一塊的知識準備分享給大家。

咱們開門見山先談 事務
  • 首先思考事務有什麼作用?
    • 事務是爲了保證數據庫中數據的完整性和一致性
  • 事務的四個基本要素 ACID ?這四要素是怎麼實現的?
    • 原子性 Atomicity
      • 原子性通過 Innodb undo log 即回滾日誌實現
    • 一致性 Consistency
      • 一致性通過 lock 鎖來實現
    • 隔離性 Isolation
      • 隔離性通過 lock 鎖和 MVCC 來實現
    • 持久性 Durability
      • 持久性通過 Innodb redo log 即重寫日誌實現 ,和 doublewrite 兩次寫技術來實現

現在我們開始談 隔離級別
  • 什麼是隔離級別 ?
    • 併發事務之間相互影響的程度,隔離級別越高影響程度就越低
    • 併發事務會造成的問題
      • 髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據
      • 不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果 不一致。
      • 幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改爲ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀
  • 隔離級別的種類
    • read-uncommitted 讀未提交
      • 讀數據時不加鎖,寫數據時加行級共享鎖
    • read-committed 不可重複讀
      • 讀數據使用 MVCC,寫數據加行級排它鎖
    • repeatable-read 可重複讀
      • 讀數據使用 MVCC,寫數據加行級排它鎖和 gap、next-key lock
        • 如果是用到了主鍵的話加鎖
    • serializable 串行化
      • 讀數據加表級共享鎖,寫數據加表級排它鎖

在 Mysql 的併發控制中我們常常需要使用到 鎖 和 MVCC,那麼這兩者的使用場景有什麼區別呢,爲什麼有了鎖還要引入 MVCC 呢?下面我將爲大家娓娓道來這兩者使用上的區別
基於鎖的併發控制
  • LBCC (Lock-Based Concurrent Control) 即基於鎖的併發控制
  • Mysql 的鎖由 共享鎖(讀鎖)排它鎖(寫鎖) 組成
  • 按粒度也可以分爲表鎖和行鎖
  • 加鎖和解鎖遵循 2PL兩階段鎖原則
  • 2PL就是將加鎖/解鎖分爲兩個完全不相交的階段。加鎖階段:只加鎖,不放鎖。解鎖階段:只放鎖,不加鎖
  • 若所有事務均遵守兩段鎖協議,則這些事務的所有交叉調度都是可串行化1

多版本的併發控制
  • MVCC 即 (Multi-Version Concurrency Control) 多版本的併發控制協議
  • MVCC 最大的好處可以概括爲讀不加鎖,讀寫不衝突
  • MVCC 併發控制中,讀操作可以分成兩類:快照讀 (snapshot read)當前讀 (current read)
    • 快照讀,讀取的是記錄的可見版本 (有可能是歷史版本),不用加鎖
      • 簡單的select操作,屬於快照讀,不加鎖。
        • SELECT * FROM user WHERE ?
    • 當前讀,讀取的是記錄的最新版本,並且,當前讀返回的記錄,都會加上鎖,保證其他事務不會再併發修改這條記錄
      • 特殊的讀操作,插入/更新/刪除操作,屬於當前讀,需要加鎖。
        • 特殊讀 (加鎖讀)
          • SELECT * FROM user WHERE ? LOCK IN SHARE MODE;
        • 插入/更新/刪除
          • SELECT * FROM user WHERE ? FOR UPDATE;
          • INSERT INTO user VALUES (…);
          • UPDATE user SET ? WHERE ?;
          • DELETE FROM user WHERE ?;

  1. 當且僅當某組併發事務的交叉調度產生的結果和這些事務的某一串行調度的結果相同,則稱這個交叉調度是可串行化 ↩︎

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