db-20 — Observation
Frozen exam hashes
| Scenario | Args | sha256 |
|---|---|---|
| A | --seed 42 --ops 500 --keys 32 --scenario default | 1febc1252f87f873c315526e9d9c78a622131d700dccca84a6e089244930252b |
| B | --seed 7 --ops 2000 --keys 128 --scenario partition | 272af5b41b729896a7195a6ea72d19111a96a50b29d5d4cdfaac03a058e1a2dc |
These three statements are all asserted by scripts/cross_test.sh:
- Rust, Go, and C++ each produce the hash above for the given scenario.
- All five replicas in the cluster produce the identical snapshot
after the scenario completes (
TestScenarioBReplicasConvergein Go,test_scenario_b_frozenin C++,scenario_b_partitioned_replicas_converge_after_healin Rust). - The cluster has no live partitions when the driver returns.
Quantitative observations
| metric | scenario A | scenario B |
|---|---|---|
| ops | 500 | 2000 |
keys parameter | 32 | 128 |
| committed-on-leader entries | 500 | 2000 |
| approximate Put / Del fraction | 3/4 vs 1/4 | 3/4 vs 1/4 |
| live keys in final state (approx) | < 32 | < 128 |
Every committed entry executes exactly once on the leader; partitioned
followers see all of them after heal() because truncate_and_replay
replays the entire log.
Behavioural observations
- Convergence is deterministic. No timeouts, no clocks. Running
the workload twice with the same seed always yields the same bytes
(
workload_determinismin Rust,TestWorkloadDeterminismin Go,test_workload_deterministicin C++). - Sub-quorum proposals leave uncommitted tails. The leader's
last_idxadvances every propose, butcommit_indexonly advances on quorum acks. This is observable in the testsub_quorum_does_not_commit— the leader seeslast_idx == 1andcommit_index == 0. - Heal is a one-shot. In scenario B, after the heal call at
ops*3/4, all five replicas have byte-identical state machines. There is no period of eventual consistency — convergence is instantaneous and deterministic by construction. - Delete is real.
Delremoves the key from the state machine. A laterPutreusing the same key is a fresh entry, not a "revive". This is asserted bytest_del_removes_key(C++) and friends.
Performance notes (this lab is not a perf study)
The reference implementations are single-threaded, in-memory, with no
I/O. Scenario B runs in ~5 ms in Release Rust on an M-series Mac;
the snapshot push during heal() is O(log_size) per partitioned
follower, which is the dominant cost.
The lab deliberately optimises for clarity and byte-identity, not throughput. Real systems (db-09 leveldb-complete is a good adjacent reference) batch and pipeline replication; here every propose is synchronous.