Constructed state traces / not a cluster experiment
Read repair: three constructed state traces
A finite example contrasts a narrow blocking repair, response-only reconciliation and a full-partition read, without running a Cassandra cluster.
Download CSV9 states / 10 columnsJSON and provenance / Model code / Research explanation
Method
Each independent scenario starts with A=(1,1), B=C=(0,0) for rows x and y of one partition after an unsuccessful quorum write reached A only. A read contacts A+B; a second read contacts B+C. Reconciliation chooses the higher generation per queried row. BLOCKING copies those rows to both participants before returning; NONE returns reconciled rows without writing. All repair writes succeed. The third scenario changes the first read from x alone to x+y.
The values 0 and 1 label old and new generations. A pair is x/y, not a fraction. Each scenario starts again from the same state. An omitted row in a response is not a zero.
Narrow read, blocking repair
| Step | Read | Returned x/y | A after | B after | C after |
|---|---|---|---|---|---|
| Initial | None | No response | 1/1 | 0/0 | 0/0 |
| Read 1 | A+B: x | 1/not read | 1/1 | 1/0 | 0/0 |
| Read 2 | B+C: x+y | 1/0 | 1/1 | 1/0 | 1/0 |
Narrow read, no repair write
| Step | Read | Returned x/y | A after | B after | C after |
|---|---|---|---|---|---|
| Initial | None | No response | 1/1 | 0/0 | 0/0 |
| Read 1 | A+B: x | 1/not read | 1/1 | 0/0 | 0/0 |
| Read 2 | B+C: x+y | 0/0 | 1/1 | 0/0 | 0/0 |
Both rows, blocking repair
| Step | Read | Returned x/y | A after | B after | C after |
|---|---|---|---|---|---|
| Initial | None | No response | 1/1 | 0/0 | 0/0 |
| Read 1 | A+B: x+y | 1/1 | 1/1 | 1/1 | 0/0 |
| Read 2 | B+C: x+y | 1/1 | 1/1 | 1/1 | 1/1 |
What the traces establish
Within these model rules, the narrow blocking read spreads x without y. Response-only reconciliation preserves the stored pairs but lets the next read return older x. Reading both rows first removes that partial state in this schedule. These are counterexamples to overbroad claims, not measurements of how often an outcome happens.
Reproduce
node --input-type=module -e 'import { toCsv } from "./read-repair-traces.mjs"; process.stdout.write(toCsv())'The dependency-free module produces the CSV from fixed inputs. JSON records the generation time, runtime and SHA-256 hashes of the code and CSV.
Limits
- Constructed finite traces, not Cassandra execution, measured traffic or reproduction of paper data.
- One partition, three full replicas, two ordered generations and two responding replicas per read; no concurrent updates, timestamp ties, expiry, deletion, speculative reads, hints, batch replay or anti-entropy.
- Repair writes are assumed successful. Failures, topology, acknowledgements, persistence and latency are not simulated.
- The chosen contact schedule is possible, not a frequency estimate or exhaustive proof of implementation behavior.
- Changing the first read's scope repairs both rows in this trace only; this does not prove general transaction isolation or recommend a production setting.
- Rows are dependent states in three separate scenarios; no statistical confidence interval is applicable.
Column definitions
- scenario
- Independent scenario label; not a sampled population.
- mode
- Model rule: BLOCKING writes selected rows to contacted replicas; NONE does not.
- step
- 0 initial state, 1 first read, 2 second read; ordering only, not elapsed time.
- participants
- Contacted replica names, joined with +; empty at initialization.
- fields
- Rows selected within one partition, joined with +; empty at initialization.
- returnedX
- Generation returned for row x; null/empty CSV means not read, never zero.
- returnedY
- Generation returned for row y; null/empty CSV means not read, never zero.
- A
- Replica A state after the step, x/y; 0 is the old generation and 1 the new generation, not an application-value ordering.
- B
- Replica B state after the step, x/y; 0 is the old generation and 1 the new generation, not an application-value ordering.
- C
- Replica C state after the step, x/y; 0 is the old generation and 1 the new generation, not an application-value ordering.
Sources and license
CC0-1.0 for Hesela's original model code and constructed traces; cited documentation retains its own license.
Concepts: read repair and anti-entropy repair.