Skip to content

Phoenix 7920 Add replay-side handling for direct DEGRADED_STANDBY → STANDBY_TO_ACTIVE transition (ANISTS → AISTS)#2573

Open
Himanshu-g81 wants to merge 13 commits into
apache:PHOENIX-7562-feature-newfrom
Himanshu-g81:PHOENIX-7920
Open

Phoenix 7920 Add replay-side handling for direct DEGRADED_STANDBY → STANDBY_TO_ACTIVE transition (ANISTS → AISTS)#2573
Himanshu-g81 wants to merge 13 commits into
apache:PHOENIX-7562-feature-newfrom
Himanshu-g81:PHOENIX-7920

Conversation

@Himanshu-g81

Copy link
Copy Markdown
Contributor

No description provided.

Himanshu Gwalani added 13 commits July 11, 2026 16:27
Capture current time at the start of initializeLastRoundProcessed() (before the HA group state read and file scans) and thread it through all three init branches - DEGRADED_STANDBY, STANDBY_TO_ACTIVE, and the SYNC path - via a new fallback-time overload on the parent. This anchors the starting round to when init began, so a SYNC -> DEGRADED_STANDBY transition during init cannot push the round (and the SYNC-path recovery floor) past the degradation point. Also documents the zero lastSyncStateTimeInMs fallback on initLastRoundsFromLastSyncPoint.
…on test

The zero-lastSyncStateTimeInMs guard in initLastRoundsFromLastSyncPoint is shared by the DEGRADED_STANDBY and STANDBY_TO_ACTIVE init paths, but only the STANDBY_TO_ACTIVE path had a zero-sync regression test. The guard also corrected the DEGRADED path (which previously computed round(min(0, frontier)) = round(0) = ReplicationRound(0,0), the epoch-rewind bug). This adds the symmetric DEGRADED_STANDBY test so a future refactor that diverges the two paths cannot silently reintroduce the epoch rewind. Test count 44 -> 45 (failsafe XML verified GREEN).
…-aware race

Cluster2 is peer-aware and auto-reacts to Cluster1's ACTIVE_NOT_IN_SYNC by
driving its own LOCAL record to DEGRADED_STANDBY during store-and-forward entry.
That reaction can still be in flight when transitionCluster2(DEGRADED_STANDBY)
runs on a slow box, so setHAGroupStatusIfNeeded could throw
InvalidClusterRoleTransitionException on a redundant same-state transition.
Poll a bounded 10s window for the record to settle at the target before the
no-op check so the transition is robust whether or not the reaction has landed.
…to fix flaky failover

The promotion poll (driveReplayUntil ACTIVE_IN_SYNC) was flaky on slow/loaded
boxes: it timed out at 120s on a 176.8s run but passed at ~57s runs. Root cause
is not the guarded Fix apache#1 code but the test harness. Cluster1's writer was left
running through Stage 3; its rotation thread emits an empty round .plog every
round-duration into Cluster2's 'in' dir. That file perpetually occupies the
[nextRoundToProcess, currentTimestampRound] window that shouldTriggerFailover()
condition 4 (getNewFiles(...).isEmpty()) scans, so promotion could only land in
a race window between the replay catching up and the next file arriving. The
failed run shows 239/239 checks blocked with 'New files exist...'.

Fix: close logGroup before the promotion drive, modeling the real failover
precondition (the old ACTIVE is gone, producing no more logs). File production
stops, the replay drains, condition 4 clears, and promotion is deterministic at
any round duration. Batch B is already forwarded (Stage 2), so the
SYNCED_RECOVERY rewind still re-replays it and zero RPO holds; close() is
idempotent so afterTest's close is a no-op. Also drop the local design-spec
path from the class javadoc (spec is not being pushed).

Verified: Tests run: 1, Failures: 0, Time elapsed 57.61s; log shows promotion
firing ~2s after writer close via 'Failover can be triggered'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant