RDBMS - 兩種 Isolation 實作機制 SX LOCK VS MVCC 原理介紹

上次的 RDBMS 介紹提到了 RDBMS 在不同 Isolation Level 下會有不一樣的 Read Phenomena,而其實在不同的資料庫中其底層 Isolation 實作是有分兩種的:

  • SX LOCK
  • MVCC

今天的文章內容是要介紹 SX LOCK 與 MVCC 原理及兩者的比較,參考:[TritonHo 大神的簡報](https://github.com/TritonHo/slides/tree/master/Taipei 2019-04 course),好教材!

SX LOCK 機制介紹

SX LOCK 其全名叫做:Shared-exclusive LOCK

首先要知道何謂 SX LOCK,也叫做:Reader-writer lock (RW LOCK)

以意思來看就是一個讀鎖,一個寫鎖。

  • 在資料庫中,每一個 Record 都有各自對應的 SX LOCK
  • 所有由交易 (TX) 擁有的 LOCK,會在 TX 結束時自動歸還鎖,但是 S LOCK 會根據 Isolation level 來決定歸還時間,所以不一定會等到 TX 結束後再歸還。
  • S LOCK 對應資料讀取鎖,X LOCK 對應資料改動鎖
  • S LOCK 可以同時發給多個 TX,所以同一時間能有多個 TX 讀取同一塊資料
  • 發行 X lock 時,Record 必須沒有其他的 LOCK,不管是 S 還是 X 都不能有。
  • 如果該 Record 被加上 X LOCK,那直到該 X lock 結束之前,該 Record 都不能發行其他的 lock,也就是直到 TX 結束時,該 Record 都不能被其他 TX 讀取 / 改動

MVCC 機制介紹

全名叫做:Multi-version concurrency control

  • 每次的 insert/update 會為該 Record 增加額外的版本

    也就是說資料庫會擁有多種版本的 Record,而每個版本都有時間紀錄,讓 RDBMS 知道哪份版本才是最新的,而 Record 太舊的版本會被 RDBMS 自動刪除。

  • 因為有版本的機制,因此在 MVCC 中只有 X LOCK,也就是寫鎖,沒有 S LOCK,也就是讀鎖。

  • MVCC 讀取時,會自動讀該 Record 最新的 Committed 版本,不會讀尚未 Committed 的版本,因此直接解決了 Dirty Read。

  • 因為只有 WRITE-WRITE conflic,所以 MVCC 的 Read 永遠不會被 Block 住

SX LOCK 與 MVCC 的比較

  • 兩者都能達到 Isolation 目的,避免 Race Condition
  • Oracle、PostgreSQL 採用 MVCC
  • MySQL、MSSQL 採用 SX LOCK

Note:雖然之前文章介紹了 ACID 與四個 Isolation Level,但因為其底層時作機制不同,會造成 Isolation 的行為有所不同,也造成不一樣的風險。

  • 在只考慮一個 TX 下,MVCC 使用比較多 IO 與 CPU,所以會比較花時間,因為:
    1. 要決定該 Record 的哪個版本才是最新
    2. 要管理舊的版本刪除機制
  • 在高流量環境,MVCC 比較高效能,因為:
    1. 因為 MVCC 的 Read 永遠不會被 Block,同一時間資料庫能處理更多 TX。
    2. MVCC 只有 X LOCK 而沒有 S LOCK,其 Deadlock dector 要管理 lock 的數目較少,所以一定比較快

總結

今天只介紹原理所以會感覺比較抽象,需要看著例子實際知道 LOCK 在甚麼時候發放會比較好懂,下篇文章帶來例子來做解釋。