chore(deps): LocalDb 0.2.0 — dereg cleanup, late-opt-in baselining, byte-budget replication
This commit is contained in:
@@ -162,21 +162,41 @@ Each site has its own two-node cluster:
|
||||
only the initiating half of a pair sets `PeerAddress` (one bidirectional stream, dialled by one
|
||||
side); the passive half carries the key alone. A deliberately unreplicated node — site-b and
|
||||
site-c on the rig — runs with no triggers at all and stops paying the per-write capture cost.
|
||||
- **Stale-trigger cleanup is automatic** (LocalDb 0.2.0). A node with no replication configured does
|
||||
not merely skip registration — at boot it calls `DeregisterReplicated` on all ten tables, dropping
|
||||
any capture triggers an earlier build installed and pruning those tables' oplog and row-version
|
||||
rows. It is idempotent, so a file that was never registered reports nothing to clean; when
|
||||
something *was* cleaned the node logs it once at Information. Recreating the data volume is no
|
||||
longer required to stop an in-place-upgraded node from capturing.
|
||||
|
||||
#### Turning replication ON for a site that has been running without it
|
||||
|
||||
Set the keys on **both** nodes and restart both. Two things to know before you do:
|
||||
**Supported as of LocalDb 0.2.0.** Set the keys on **both** nodes and restart both (see the
|
||||
stop-and-start-together rule below — this is a pair-wide change, not a rolling one). Existing rows
|
||||
are carried across:
|
||||
|
||||
- **Existing rows are not baselined.** Capture is change-data-capture: rows written while the node
|
||||
had no triggers were never recorded in `__localdb_row_version`, and LocalDb's snapshot resync
|
||||
streams from that ledger, so it will not ship them. The pair converges on everything written
|
||||
*after* the restart and stays silently divergent on everything before it. Start from a copy of one
|
||||
node's database on both sides, or accept that only new writes converge.
|
||||
- **A node upgraded in place keeps stale triggers.** The guard decides whether triggers are
|
||||
*installed*, not whether existing ones are removed, and the library has no removal API yet. A
|
||||
database file first created by a build that always registered keeps capturing until that lands.
|
||||
Recreating the node's data volume clears it — which is what a schema-change redeploy does on the
|
||||
docker rig, so the rig is unaffected.
|
||||
- **Pre-existing rows are baselined automatically.** ScadaBridge registers every replicated table
|
||||
with `baselineExistingRows: true`. Capture is change-data-capture, so rows written while the node
|
||||
had no triggers appear in neither the oplog nor `__localdb_row_version` — and LocalDb's snapshot
|
||||
resync streams from that ledger. Baselining seeds the ledger for those rows at the LWW floor
|
||||
(HLC `0`, stamped with the node's own id) and flags a snapshot resync, so the peer actually
|
||||
receives them. Copying one node's database onto the other beforehand is no longer necessary.
|
||||
- **What the floor means for conflicts.** Every genuine HLC is a UTC millisecond shifted left 16
|
||||
bits, so it is strictly greater than `0`: a baselined row loses to any real remote write of the
|
||||
same key and wins only where the peer holds no version of that key at all. The one ambiguous case
|
||||
is **both** nodes baselining the same key (e.g. both were restored from the same legacy file) —
|
||||
both hold HLC `0` and the node-id tie-break decides. That is convergent but arbitrary as to which
|
||||
content survives, so if the two files may disagree on a key, start both nodes from one node's
|
||||
database.
|
||||
- **Seeding is idempotent** (`ON CONFLICT DO NOTHING`), so a row that already has a genuine version
|
||||
keeps it and no snapshot is flagged. Booting with baselining on every start is free after the
|
||||
first.
|
||||
|
||||
Turning replication back **OFF** is likewise a both-nodes change: deregistration must be symmetric,
|
||||
because the sync handshake compares the two nodes' registered-table digests fail-closed — a node
|
||||
that drops a table its peer still replicates stops syncing with a schema-mismatch error rather than
|
||||
diverging silently. Turning it on again later re-baselines, which is what makes the ledger prune on
|
||||
deregistration safe.
|
||||
|
||||
### Site Pair Upgrades — stop and start BOTH nodes together
|
||||
|
||||
|
||||
Reference in New Issue
Block a user