繼續學 Isolation...

在「測試 MariaDB 上 Galera Cluster 的 Isolation」這邊與「從頭學一次 Isolation level 的 REPEATABLE-READ 與 SERIALIZABLE」對應了 Stripe 的「Call me Maybe: MariaDB Galera Cluster」以及 Percona 的「Clarification on “Call me Maybe: MariaDB Galera Cluster”」這兩篇文章,兩邊在空中交火...

而「Call me Maybe: Percona XtraDB Cluster」這篇是目前最新的一篇 (文章日期有點怪怪的,不應該是 2015/09/04)。

畢竟 Galera Cluster 是目前現在在用的產品,雖然跑起來也沒什麼大問題,但預先多了解一點總是比較保險。而要參與這場 Isolation 戰爭,又花了不少時間看幾份資料。(包括重頭讀的)

第一個當然是 1992 年發表的 SQL-92:「ISO/IEC 9075:1992, Database Language SQL」,在 SQL-92 定義了四個 Isolation 的層級,分別是 SERIALIZABLEREPEATABLE READREAD COMMITTEDREAD UNCOMMITTED

另外一篇常被拿出來討論的是 1995 年由微軟帶頭發表的「A Critique of ANSI SQL Isolation Levels」,主要是提出 Snapshot Isolation 的定義。

後來讀到覺得真的很怪的時候到 Stack Exchange 上的 Database Administrators 問:「Does SQL92's REPEATABLE-READ preclude Write Skew (A5B)?」,確認了我的想法。

這篇算是讀書心得吧,留給自己用的 :p

首先是 REPEATABLE READ 的定義是透過「現象」定義,只要符合這些條件就可以被稱作 REPEATABLE READ,這包括了保證不會出現 P1 ("Dirty read"):

1) P1 ("Dirty read"): SQL-transaction T1 modifies a row. SQL-transaction T2 then reads that row before T1 performs a COMMIT. If T1 then performs a ROLLBACK, T2 will have read a row that was never committed and that may thus be considered to have never existed.

以及保證不會出現 P2 ("Non-repeatable read"):

2) P2 ("Non-repeatable read"): SQL-transaction T1 reads a row. SQL-transaction T2 then modifies or deletes that row and performs a COMMIT. If T1 then attempts to reread the row, it may receive the modified value or discover that the row has been deleted.

並且保證 Atomicity 以及 no updates will be lost:

The four isolation levels guarantee that each SQL-transaction will be executed completely or not at all, and that no updates will be lost.

只要做到這些條件,就可以說符合 SQL-92 的 REPEATABLE READ 要求。


另外一方面,在「A Critique of ANSI SQL Isolation Levels」定義的 SQL-92 認為 REPEATABLE READ 是透過 locking 機制實作的 (整篇的寫法的確是朝這個方向走),並且基於 locking mechanism 來推論後續的行為,所以這篇 paper 裡面很多說明是帶著這個大前提的。

而當時已經有資料庫是使用 MVCC 架構在實作,可以透過 read snapshot 的方式找出另外一條路。

舉例來說,InnoDB 對 REPEATABLE READ 實作的方式是透過 snapshot 實作:(出自「MySQL :: MySQL 5.6 Reference Manual :: 13.3.6 SET TRANSACTION Syntax」)

For consistent reads, there is an important difference from the READ COMMITTED isolation level: All consistent reads within the same transaction read the snapshot established by the first read. This convention means that if you issue several plain (nonlocking) SELECT statements within the same transaction, these SELECT statements are consistent also with respect to each other.

這樣避開了 P1、P2 (甚至多做避開到了 P3,不過這邊不重要),並且 Atomicity。而 Update Lost 問題則再透過 lock 機制避免。所以 InnoDB 的 REPEATABLE READ 其實比 SQL-92 的要求多做到了很多事情...


到這邊再回頭看原來的討論文章,才會發現 Isolation 裡有滿滿的地雷可以採 XD

Leave a Reply

Your email address will not be published. Required fields are marked *