mysql MVCC原理理解


      MVCC多版本控制: 指的是一種提高並發的技術。最早的數據庫系統,只有讀讀之間可以並發,讀寫,寫讀,寫寫都要阻塞。引入多版本之后,只有寫寫之間相互阻塞,其他三種操作都可以並行,這樣大幅度提高了InnoDB的並發度。在內部實現中,與Postgres在數據行上實現多版本不同,InnoDB是在undolog中實現的,通過undolog可以找回數據的歷史版本。找回的數據歷史版本可以提供給用戶讀(按照隔離級別的定義,有些讀請求只能看到比較老的數據版本),也可以在回滾的時候覆蓋數據頁上的數據。在InnoDB內部中,會記錄一個全局的活躍讀寫事務數組,其主要用來判斷事務的可見性。
      MySQL的大多數事務型存儲引擎實現的都不是簡單的行級鎖。基於提升並發性能的考慮,它們一般都同時實現了多版本並發控制(MVCC)。不僅僅是MySQL,包括Oracle,PostgreSQL等其他數據庫系統也都實現了MVCC,但是各自的實現機制並不相同,因為MVCC並沒有一個統一的標准。MVCC在很多情況下避免了加鎖操作,因此開銷更低。大多數的MVCC都實現了非阻塞的讀操作,寫操作也只鎖定必要的行。
     MVCC的實現,是通過保存數據在某個時間點的快照來實現的。也就是說,不管需要執行多長時間,每個事務看到的數據是一致的。根據事務開始的時間不同,每個事物對同一張表,同一時刻看到的數據可能是不一樣的。不同存儲引擎的MVCC實現是不同的,典型的有樂觀(optimistic)並發控制和悲觀(pessimistic)並發控制。

     MVCC只在REPEATABLE READ和READ COMMITTED兩個隔離級別下工作。其他兩個隔離級別都和MVCC不兼容,因為READ UNCOMMITTED總是讀取最新的數據行,而不是符合當前事務版本的數據行,而SERIALIZABLE會對所有讀取到的行都加鎖。

    MVCC的優缺點:

    MVCC的目標是追求數據庫處理高並發能力,實現了非阻塞的讀操作。

    但保存這兩個額外的系統版本號,使大多數讀操作都可以不用加鎖,這樣設計使得讀數據操作很簡單,性能很好,並且也能保證只會讀取到符合標准的行,不足之處是每行記錄都需要額外的存儲空間,需要做更多的行檢查工作,以及一些額外的維護工作。

 附:事務隔離級別

  數據庫事務具備ACID特性,即Atomicity(原子性) Consistency(一致性), Isolation(隔離性), Durability(持久性)

  原子性:要執行的事務是一個獨立的操作單元,要么全部執行,要么全部不執行

  一致性:事務的一致性是指事務的執行不能破壞數據庫的一致性,一致性也稱為完整性。一個事務在執行后,數據庫必須從一個一致性狀態轉變為另一個一致性狀態。

  隔離性:多個事務並發執行時,一個事務的執行不應影響其他事務的執行,SQL92規范中對隔離性定義了不同的隔離級別:

       讀未提交(READ UNCOMMITED)->讀已提交(READ COMMITTED)->可重復讀(REPEATABLE READ)->序列化(SERIALIZABLE)。隔離級別依次增強,但是導致的問題是並發能力的減弱。

隔離級別

臟讀

不可重復讀

幻讀

概念

READ UNCOMMITED

事務能夠看到其他事務沒有提交的修改,當另一個事務又回滾了修改后的情況,又被稱為臟讀dirty read

READ COMMITTED

×

事務能夠看到其他事務提交后的修改,這時會出現一個事務內兩次讀取數據可能因為其他事務提交的修改導致不一致的情況,稱為不可重復讀

REPEATABLE READ

×

×

事務在兩次讀取時讀取到的數據的狀態是一致的

SERIALIZABLE

×

×

×

可重復讀中可能出現第二次讀讀到第一次沒有讀到的數據,也就是被其他事務插入的數據,這種情況稱為幻讀phantom read, 該級別中不能出現幻讀

   大多數數據庫系統的默認隔離級別都是READ COMMITTED(但MySQL不是),InnoDB存儲引擎默認隔離級別REPEATABLE READ,通過多版本並發控制(MVCC,Multiversion Concurrency Control)解決了幻讀、不可重復讀的問題。

      臟讀(Drity Read):某個事務已更新一份數據,另一個事務在此時讀取了同一份數據,由於某些原因,前一個RollBack了操作,則后一個事務所讀取的數據就會是不正確的。

     不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中數據不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的數據。

     幻讀(Phantom Read):在一個事務的兩次查詢中數據筆數不一致,例如有一個事務查詢了幾列(Row)數據,而另一個事務卻在此時插入了新的幾列數據,先前的事務在接下來的查詢中,就會發現有幾列數據是它先前所沒有的。

     注:1、不可重復讀的和幻讀區別,不可重復讀側重於修改,幻讀側重於新增或刪除。解決不可重復讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表。

            2、MVCC對於已提交讀隔離級別下的事務在每次查詢的開始都會生成一個獨立的ReadView,而可重復讀隔離級別則在第一次讀的時候生成一個ReadView,之后的讀都復用之前的ReadView。通過版本鏈,實現多版本,可並發讀-寫,寫-讀。通過ReadView生成策略的不同實現不同的隔離級別。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM