fix(mariadb): fail closed after uncertain DCS switchover to avoid split-brain#3066
Draft
weicao wants to merge 1 commit into
Draft
fix(mariadb): fail closed after uncertain DCS switchover to avoid split-brain#3066weicao wants to merge 1 commit into
weicao wants to merge 1 commit into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3066 +/- ##
=====================================
Coverage 0.00% 0.00%
=====================================
Files 144 144
Lines 23053 23077 +24
=====================================
- Misses 23053 23077 +24 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…it-brain The Stage-3 (DCS switchover) failure path in replication-switchover.sh called rollback_current_primary_switchover_guard, which sets the current primary back to read_only=0 and restores its remote-root write grants. syncerctl_switchover runs with --force under a timeout(1) wrapper, so a non-zero / timeout (rc 124/125/137) return does not prove the DCS switchover record was never persisted: syncer may already be asynchronously promoting the candidate. switchover_final_state_already_reached only detects the fully completed end state, so during the in-progress window it returns false and the old rollback un-fences the still-writable old primary. When syncer finishes promoting the candidate, both nodes accept writes = split-brain. Fail closed instead: fence the current primary (read_only=1) via a new fence_current_primary_after_uncertain_dcs helper. Rollback-to-writable remains only on the Stage-2 pre-DCS path, where syncerctl was never invoked and no DCS record can exist. Fixes #3065
2ada269 to
baf11e6
Compare
Contributor
Author
|
rebase 到 main 554fd84 + re-author 为 Magnus magnus@apecloud.com + 按 org 规范移除 AI 署名 trailer。内容零变化。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary (H2)
In
addons/mariadb/scripts/replication-switchover.sh, the Stage-3 (DCS switchover) failure path callsrollback_current_primary_switchover_guard, which sets the current primary back toread_only=0and restores its remote-root write grants. This can produce a split-brain with two writable primaries.Root cause
syncerctl_switchoveris invoked with--forceand wrapped bytimeout(1):A non-zero / timeout return does not prove the DCS switchover record was never persisted. Syncer can accept and persist the request, begin asynchronously promoting the candidate, and then have its client (
syncerctl) killed by the wall-clock budget.On that return,
run_switchoverdoes:switchover_final_state_already_reachedonly detects the fully-completed end state (candidate already primary + current following it). During the in-progress window (syncer still promoting), it returns false, so rollback runs and un-fences the old primary. Under the alpha.79 minimalist model the old primary is still fully writable at this point (prepare_current_primary_for_switchoveris a no-op; the Stage-4 fence has not run yet), so rollback actively guarantees it stays writable. When syncer then finishes promoting the candidate (also writable), both nodes accept writes.Rollback-to-writable is only safe before
syncerctlis ever invoked — i.e. the Stage-2 pre-DCS failure path (wait_candidate_sql_reachable_before_dcs), where no DCS record can exist. That call site is unchanged.Fix
First principles: once the DCS write cannot be proven to have not landed, fail closed. On the Stage-3 failure path, fence the current primary (
read_only=1) instead of rolling it back to writable, via a newfence_current_primary_after_uncertain_dcshelper. If the DCS record truly did not persist, KB roleProbe + reconcile converge the still-read_only old primary (and the failed OpsRequest may retry the whole switchover) — a bounded, recoverable availability blip, always preferable to unbounded split-brain writes.Tests
addons/mariadb/scripts-ut-spec/replication_switchover_spec.shupdated: the two Stage-3-failure cases now assert the current primary is fenced (set_read_only=ON), never unfenced (set_read_only=OFF), androllbackis not called; plus a new case asserting a manual-verification error is surfaced when the fail-closed fence itself cannot be applied. Full mariadb suite: 664 examples, 0 failures.