You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/design-docs/EmergencyReparentShard.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,5 +22,6 @@ The goals, rules and limitations of ERS. Changes to `go/vt/vtctl/reparentutil` m
22
22
- Automated ERS callers such as VTOrc must never allow a split-brain promotion; resolving a split brain requires an operator to choose the history to preserve
23
23
- The most-advanced tablet becomes the intermediate source, which is a replication source and not an automatic winner: the final primary must come from the filtered valid candidates, and catch up to the intermediate source before the switch
24
24
-`PopulateReparentJournal` on the promoted primary is the system of record for promotions: errant GTID detection counts journal rows to decide which tablets can serve as evidence, so every promotion must write it
25
+
- A tablet with an empty GTID position cannot corroborate evidence or be promoted over tablets with real history; its surviving reparent journal rows still count as proof of promotion history. When every tablet holding the deepest journal history has an empty position, including when all positions are empty on a shard whose journal shows history, ERS must fail closed, because the remaining candidates provably missed a promotion whose content can no longer be proven. Only a shard with empty positions and empty journals everywhere, and whose topology has never recorded a primary, is treated as uninitialized, where every candidate is an equally valid first primary
25
26
- The reparent sorter (via `ElectNewPrimary`) and durability helpers like `canEstablishForTablet` are shared with `PlannedReparentShard`: changes to candidate ordering or semi-sync accounting affect PRS too
26
27
- Any new pipeline step that stops replication on a tablet must add that tablet to `replicasToRestart`, so the deferred cleanup can recover it if ERS aborts. The code can't enforce this — review carefully
// Find the candidates with the maximum length of the reparent journal.
1374
+
// A shard where every candidate has an empty GTID position and an empty reparent
1375
+
// journal has never seen a promotion: it is being initialized, and every candidate
1376
+
// is an equally valid first primary. The topology must agree the shard was never
1377
+
// initialized, though: a shard that has recorded a primary has history to protect
1378
+
// even when every reachable tablet lost both its GTIDs and its sidecar tables.
1379
+
// Empty positions alongside journal history mean the GTID state was wiped instead,
1380
+
// which fails closed below.
1381
+
ifallPositionsZero&&maxLen==0 {
1382
+
if!shardNeverInitialized {
1383
+
returnnil, nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "every candidate reports an empty GTID position and an empty reparent journal, but the shard topology records a previous primary: refusing to re-initialize a shard that has history to protect; restore a tablet with the shard's data before retrying")
1384
+
}
1385
+
returnmaps.Clone(validCandidates), nil, nil
1386
+
}
1387
+
1388
+
// A tablet with nil or zero positions has no GTIDs to corroborate anyone and can't be
1389
+
// promoted over tablets with real history, so it is dropped from candidacy up front.
returnnil, nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "errant GTID detection has no usable evidence: the candidates with the latest reparent journal history (%s, %d entries) have empty GTID positions, so the remaining candidates cannot be proven to have seen the latest promotion; restore the GTID state or data of a wiped tablet before retrying; removing the wiped tablets from the shard instead would discard the missed promotion's transactions", strings.Join(wipedLeaders, ", "), maxLen)
1370
1426
}
1371
1427
1372
1428
// We use all the candidates with the maximum length of the reparent journal to find the errant GTIDs amongst them.
0 commit comments