docs(localdb): live-gate the two Phase 1 follow-ups; pin LocalDb 0.1.3
The gate closed both follow-ups on the docker-dev rig and found a third defect that offline tests could not have found first: it lived behind the one being fixed. Once 0.1.2 made back-fill work, a rebuilt node could be observed writing for the first time — and its writes went nowhere, because the healthy node kept the old peer's seq watermark. Library 0.1.1 -> 0.1.2 -> 0.1.3 over the course of the gate; both consumers now pinned to 0.1.3. Check 4 (was PARTIAL, now PASS): with SQL stopped and site-a-2's LocalDb volume destroyed, a-1 logged "Snapshot sent (as_of_seq 0, 4 rows)" — a line that could not appear on 0.1.1 — and a-2 came back with a row_version dump byte-identical to a-1's, carrying a-1's origin node ids and its ORIGINAL applied_at_utc. It then booted from cache and served 17 ns=2 nodes, diff-identical to its peer, from a configuration it never applied and could not have fetched. Check 8 (PASS): two restarts with an unchanged artifact left the oplog at 7 and the pointer timestamp frozen — the re-cache was skipped outright. Positive control: a real config change still wrote, 7 -> 10 -> 13. Also records one unrelated pre-existing finding the gate's SQL flapping surfaced: a transient ConfigDb error during artifact load empties the served address space while logging "rebuild becomes no-op". The cache layer correctly refused to store the bad artifact and the node recovered on restart, but the two logs disagree and it is the same class as the Phase 1 gate's check-3 defect. Untouched by this work; wants its own issue. Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
@@ -61,7 +61,8 @@ missed**, each now fixed on-branch with a regression test:
|
||||
- **No replication back-fill of a fully-wiped node** (check 4): a peer's already-acked cache rows are
|
||||
pruned from its oplog and snapshot-resync is gated on the (never-hit) oplog cap, so a wiped node is
|
||||
not healed by its peer — it self-heals from central on next boot instead.
|
||||
→ **FIXED in `ZB.MOM.WW.LocalDb` 0.1.2** (scadaproj `cad3bcb`). The diagnosis in this doc was
|
||||
→ **FIXED in `ZB.MOM.WW.LocalDb` 0.1.2 + 0.1.3** (scadaproj `cad3bcb` + `3b7489a`), live-gated in
|
||||
`2026-07-21-localdb-followups-live-gate.md`. The diagnosis in this doc was
|
||||
slightly off: the cap was not the gate. `ComputeSnapshotRequiredAsync` measured the peer's gap
|
||||
against the *oldest surviving oplog row* and read an empty oplog as "no gap possible" — and an
|
||||
empty oplog is the **steady state of a converged pair**, since ack-pruning deletes everything the
|
||||
@@ -69,7 +70,11 @@ missed**, each now fixed on-branch with a regression test:
|
||||
an empty oplog the gap is now measured against `last_acked_seq`. Covered at both levels:
|
||||
`SnapshotResyncTests.WipedPeer_AfterEverythingWasAckedAndPruned_StillGetsSnapshot` in the library,
|
||||
and `LocalDbPairConvergenceTests.WipedNode_IsBackFilledByItsPeer_WithoutAnyNewDeploy` here —
|
||||
the latter verified RED against the pinned 0.1.1 and green on 0.1.2.
|
||||
the latter verified RED against the pinned 0.1.1 and green on 0.1.2. **0.1.3 closes a second,
|
||||
deeper half that only became reachable once back-fill worked:** the rebuilt node's OWN writes were
|
||||
silently dropped, because `last_applied_remote_seq` is a watermark in the *peer's* seq space and a
|
||||
rebuilt peer numbers from 1 again. The follow-up live gate caught that one — offline tests could
|
||||
not have, since the scenario had no test while it was still a documented limitation.
|
||||
- **Oplog growth on default-OFF nodes** (check 8): `OnReady` registers replication unconditionally, so
|
||||
a node with no peer accumulates unacked/unpruned oplog rows (~2/deploy). Slow, bounded by the 1M cap;
|
||||
a periodic pruner or a skip-if-unchanged cache write would close it.
|
||||
@@ -84,4 +89,5 @@ missed**, each now fixed on-branch with a regression test:
|
||||
the **7-day `MaxOplogAge`** cap prunes — the true bound was ~7 days of writes, not 1M rows.
|
||||
|
||||
Merged to `master` as `c957db52` (2026-07-21) and pushed. Both follow-ups closed on
|
||||
`fix/localdb-phase1-followups` (2026-07-21).
|
||||
`fix/localdb-phase1-followups` (2026-07-21) and live-gated — see
|
||||
`2026-07-21-localdb-followups-live-gate.md`, which found a third defect in the process.
|
||||
|
||||
Reference in New Issue
Block a user