三津石智巳

👦🏻👦🏻👧🏻 Father of 3 | 🗺️ Service Reliability Engineering Manager at Rakuten Travel | 📚 Avid Reader | 👍 Wagashi | 👍 Caffe Latte | 👍 Owarai

【感想】Consistency Models - Jepsen


consistency modelsがまだまだ体得できていない。anomaliesから整理するのが個人的には覚えやすそう。

に沿ってanomaliesを下記7つに整理してみる。

read anomalies

  • dirty reads (read uncommitted objects)
  • nonrepeatable reads / fuzzy read (read one committed object differently)
  • read skew (read two or more committed objects differently)
  • phantom reads (read two or more committed objects within a range differently)

write anomalies

  • dirty write (write to uncommitted objects)
  • lost update (write to one committed object differently)
  • write skew (write to two or more committed objects differently)

nonrepeatable readとread skewの違いはone object/two or more objectsかどうかで微妙だが、いずれにしてもsnapshot isolation以上で防ぐことができる。

個人的にはwrite skewが1番理解が難しい。

A generalisation of the lost update problem is when two or more concurrent transactions read the same objects, and then update some of those objects (the transactions might be updating different objects). If the transactions update the same object, a lost update can happen. If they are updating different objects, a write skew can happen. Write skews are also a very common defect that you would have come across in the wild.

https://ketanbhatt.com/db-concurrency-defects/

他に、Analyzing a read-only transaction anomaly under snapshot isolation | Johann Schleier‑Smithというanomalyも近年発見されている。

これらのanomaliesであるが、transactionの文脈で話しているのか、replicationの文脈で話しているのかは常に区別しておく必要がある。

なお、個人的にはread anomaliesよりもwrite anomaliesの方に実務上の興味がある。ただし、read anomaliesによって引き起こされるwrite anomaliesがある。例えば、phantom readによってwrite skewが引き起こされる等。結局は両方理解する必要がある。

"This is not a new problem—it has been like this since the 1970s, when weak isolation levels were first introduced [2]. All along, the answer from researchers has been simple: use serializable isolation!"

via Check out this quote from Designing Data-Intensive Applications - https://learning.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/ch07.html

7つのanomaliesを理解したところで、serializable isolationを使えば「全て」解決!というところから議論をスタートさせると良い。Designing Data-Intensive Applicationsであげられている実装は下記の通り。

  • Actual Serial Execution
  • Two-Phase Locking (2PL)
  • Serializable Snapshot Isolation (SSI)

"The approach of executing transactions serially is implemented in VoltDB/H-Store, Redis, and Datomic [46, 47, 48]."

via Check out this quote from Designing Data-Intensive Applications - https://learning.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/ch07.html

私の好きなRedisはActual Serial Executionを採用している。

"For this reason, systems with single-threaded serial transaction processing don’t allow interactive multi-statement transactions. Instead, the application must submit the entire transaction code to the database ahead of time, as a stored procedure."

via Check out this quote from Designing Data-Intensive Applications - https://learning.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/ch07.html

余談ぽい流れだが、stored procedureはシングルスレッドのactual serial executionのために使われると書いてある。なるほど。

In this model, read committed prohibits:

  • P0 (Dirty Write): w1(x) … w2(x)
  • P1 (Dirty Read): w1(x) … r2(x)

but allows:

  • P2 (Fuzzy Read): r1(x) … w2(x)
  • P3 (Phantom): r1(P) … w2(y in P)

Read Committed

上記をどう読むかというと、例えばP0 (Dirty Write)とは、transaction 1がdata xに対してwriteのcommit/abortする前に、transaction 2がdata xに対してwriteをすること、と読む。
read committedで困るユースケースとしてあげられているのは、

  • backups
  • analytic queries and integrity checks

なるほど。
でかいデータを復元・比較するようなユースケースでは、全体の一部でもdirty readが残っているとたしかに困る。

which specifies snapshot isolation as a combination of four properties:

  • Internal consistency: within a transaction, reads observe that transaction’s most recent writes (if any)
  • External consistency: reads without a preceding write in transaction T1 must observe the state written by a transaction T0, such that T0 is visible to T1, and no more recent transaction wrote to that object.
  • Prefix: transactions become visible to all nodes in the same order
  • NoConflict: if two transactions write to the same object, one must be visible to the other.

Snapshot Isolation

snapshot isolationは、MVCCによって実装される。ただし、read committedもsnapshot isolationもMVCCによって実装されることが多く、ストレージエンジンがMVCCを提供することとconsistency modelの間に直接的な関係はない。例えば、WiredTigerはストレージエンジンとしてMVCCを提供しているが、MongoDBとしてのデフォルトはread uncommittedとなる。
Read Isolation, Consistency, and Recency — MongoDB Manual