8.1 The Meaning of ACID
Coined 1983 by Theo Härder and Andreas Reuter, to establish precise terminology for fault-tolerance mechanisms.
Coined 1983 by Theo Härder and Andreas Reuter, to establish precise terminology for fault-tolerance mechanisms.
In practice, one database's implementation of ACID does not equal another's. There is a lot of ambiguity around isolation. The high-level idea is sound, but the devil is in the details. Today, when a system claims to be "ACID compliant," it's unclear what guarantees you can actually expect. "ACID" has unfortunately become mostly a MARKETING TERM.
(And BASE — basically available, soft state, eventual consistency — is even more vague. The only sensible definition of BASE is "not ACID.")
1.1 Atomicity — really "abortability"
In ACID, atomicity is NOT about concurrency. It does not describe what happens if several processes access the same data at once — that's covered under I, for isolation.
ACID atomicity describes what happens if a client wants to make several writes but a FAULT OCCURS AFTER SOME OF THE WRITES HAVE BEEN PROCESSED — a process crashes, a network connection is interrupted, a disk becomes full, or an integrity constraint is violated. The transaction is aborted and the database must discard or undo any writes it made.
Why it matters: without atomicity, if an error occurs partway through, it's difficult to know which changes took effect and which didn't. The application could try again — but that risks making some changes twice, leading to duplicate or incorrect data.
The ability to abort a transaction on error and have all its writes discarded is THE DEFINING FEATURE of ACID atomicity. Perhaps ABORTABILITY would have been a better term.
1.2 Consistency — the letter that doesn't belong
"Consistency" has at least FIVE meanings in this book:
| # | Meaning | Where |
|---|---|---|
| 1 | Replica consistency / eventual consistency | Ch 6 |
| 2 | A consistent snapshot — the whole DB as it existed at one moment; precisely, consistent with the happens-before relation: if it contains a value written at a time, it also reflects all writes that happened before that write | Ch 6, Ch 8 |
| 3 | Consistent hashing — a sharding/rebalancing approach | Ch 7 |
| 4 | Linearizability — what "C" means in the CAP theorem | Ch 10 |
| 5 | ACID consistency — an application-specific notion of the database being in a "good state" | Ch 8 |
ACID consistency = INVARIANTS that must always be true — e.g. in an accounting system, credits and debits across all accounts must always be balanced. If a transaction starts valid and its writes preserve validity, invariants are always satisfied. (An invariant may be temporarily violated DURING execution, but must be satisfied again AT COMMIT.)
To have the database enforce them, declare them as constraints in the schema: foreign-key constraints, uniqueness constraints, check constraints (restricting values in an individual row). More complex requirements can sometimes be modeled with triggers or materialized views.
However, complex invariants can be difficult or impossible to model with the constraints databases usually provide. Then it's the APPLICATION'S responsibility to define its transactions correctly. If you write bad data violating your invariants but you haven't declared those invariants, THE DATABASE CAN'T STOP YOU.
As such, the C in ACID often depends on how the application uses the database and is NOT A PROPERTY OF THE DATABASE ALONE.
1.3 Isolation
The counter is 42 and two clients each increment it. The expected result is 44.
The result is 43. One increment has been lost.
Isolation means concurrently executing transactions are isolated from each other; they cannot step on each other's toes. The classic textbooks formalize isolation as SERIALIZABILITY: each transaction can pretend it is the only transaction running on the entire database. The database ensures that when the transactions have committed, THE RESULT IS THE SAME AS IF THEY HAD RUN SERIALLY, even though in reality they may have run concurrently.
But: serializability has a performance cost. Many databases use weaker isolation. Some popular databases, such as Oracle, DON'T EVEN IMPLEMENT IT — Oracle has an isolation level called "serializable," but it actually implements SNAPSHOT ISOLATION, which is weaker.
1.4 Durability
The promise that after a transaction commits successfully, any data it wrote will not be forgotten, even if there is a hardware fault or the database crashes.
- Single-node: written to nonvolatile storage. Regular file writes are buffered in memory, so databases use
fsync. Plus a write-ahead log for crashes partway through a write, and checksums to detect corrupted or incomplete log entries. - Replicated: data successfully copied to a certain number of nodes. The database must wait until these replications complete before reporting success.
Perfect durability does not exist; if all your hard disks and all your backups are destroyed at the same time, there's obviously nothing your database can do to save you.
The eight-point reality check on durability (this list is the most sobering in the chapter):
- Write to disk and the machine dies → the data is not lost, but inaccessible until you fix the machine or move the disk. Replicated systems can remain available.
- A correlated fault — a power outage, or a bug that crashes every node on a particular input — knocks out all replicas at once, losing anything held only in memory. So writing to disk is still relevant for replicated databases.
- Asynchronous replication → recent writes are lost when the leader becomes unavailable.
- On a sudden power cut, SSDs have been shown to sometimes violate the guarantees they are supposed to provide; even
fsyncisn’t guaranteed to work correctly. Disk firmware has bugs (drives failing after exactly 32,768 hours). Andfsyncis hard to use — even PostgreSQL used it incorrectly for over 20 years. - Subtle storage-engine/filesystem interactions cause hard-to-track bugs that corrupt files after a crash. Filesystem errors on one replica can spread to others.
- Data on disk can gradually become corrupted without being detected. If it has been corrupt for some time, replicas and recent backups may also be corrupt — you need a historical backup.
- 30%–80% of SSDs develop at least one bad block in the first four years; only some are correctable by firmware. HDDs have fewer bad sectors but a higher rate of total failure.
- A worn-out SSD disconnected from power can start losing data within weeks to months, depending on temperature.
“No one technique can provide absolute guarantees. There are only various risk-reduction techniques — writing to disk, replicating to remote machines, and backups — and they can and should be used together.”