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,所以會比較花時間,因為:
- 要決定該 Record 的哪個版本才是最新
- 要管理舊的版本刪除機制
- 在高流量環境,MVCC 比較高效能,因為:
- 因為 MVCC 的 Read 永遠不會被 Block,同一時間資料庫能處理更多 TX。
- MVCC 只有 X LOCK 而沒有 S LOCK,其 Deadlock dector 要管理 lock 的數目較少,所以一定比較快
總結
今天只介紹原理所以會感覺比較抽象,需要看著例子實際知道 LOCK 在甚麼時候發放會比較好懂,下篇文章帶來例子來做解釋。