A consistency model is a promise about histories
What kind of thing is a consistency model, and why can a guarantee not be observed from inside the system?
Nothing to point at
The earlier subjects one might study about a database are all components. Each has something you can point at: a disk, a page layout, an index structure, a lock manager, a commit protocol. Consistency and isolation have nothing to point at. Each item here is a predicate over histories. A predicate is a rule that says yes or no. Here the rule says which sequences of observed reads and writes the system promises never to produce.
You cannot implement linearizability. You can only build something that satisfies it. The two things are easy to confuse, so keep these pairs in mind:
| A mechanism (how) | A predicate (what is promised) |
|---|---|
| MVCC (keeping several row versions) | Snapshot isolation |
| The pivot test used by serializable snapshot isolation (SSI) | Serializability |
| A lock manager, two-phase locking (2PL) | Serializability, or a weaker level |
| Leader plus quorum replication | Linearizability |
Snapshot isolation (SI), defined fully in Transactional isolation, is a promise about what a reader will and will not see. MVCC is one way of keeping that promise. The same promise can be kept by other mechanisms, and the same mechanism can keep different promises.
Three things change completely
The subject becomes a contract, and the other party is the application. Many design choices in a database are sold as throughput: "this weaker setting is faster". This mechanism is where the invoice arrives, and the invoice is always paid in application code: a branch that somebody must write to survive an interleaving the engine has chosen not to prevent. This is the first topic in which the failure is someone else's bug. The database did what it promised. The application assumed a stronger promise.
The guarantee cannot be observed from inside the system. A violation is a property of a global history, and nobody holds the global history. A node that serves a stale value is behaving correctly by every local check it can run. The anomaly exists only in the union of several observers' timelines, for example in what Anika saw and what Sam saw. So, unlike a disk or a cache, you cannot add a counter and measure correctness. Checking whether a general history is linearizable is NP-complete (Gibbons and Korach). NP-complete means that no fast general method is known, and one is believed not to exist. The practical tool (the testing framework Jepsen, and its checker Elle) works from outside and after the fact: it records operations, infers a dependency graph between them, and looks for cycles in it. We return to this at the end of The unification and its price.
Cost stops growing with data. In every other part of a database, cost grows with the number of bytes, rows or operations. Consistency costs in proportion to the number of vantage points (places from which someone can look at the data) and the distance between them. A single-observer system gets serializability and linearizability for free, at any data volume. Add one read replica, one cache, one second region, and the same workload over the same bytes now costs a round trip per operation. This is the only cost across the platform that is a function of topology alone. We call this the observer-count rule: consistency cost depends on how many observers exist and how far apart they are, not on how much data there is.
Anika's replica is exactly this. She added one observer. She did not change one write.