This is an automated email from the ASF dual-hosted git repository.
tkhurana pushed a commit to branch PHOENIX-7562-feature-new
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/PHOENIX-7562-feature-new by
this push:
new 1355514aaf PHOENIX-7566 HAGroupStore state machine: ANISTS
non-blocking, DS->STANDBY_TO_ACTIVE (#2518)
1355514aaf is described below
commit 1355514aaf73d3e8880d492360b035542b122a8c
Author: ritegarg <[email protected]>
AuthorDate: Thu Jun 18 10:40:25 2026 -0700
PHOENIX-7566 HAGroupStore state machine: ANISTS non-blocking,
DS->STANDBY_TO_ACTIVE (#2518)
* PHOENIX-7566 HAGroupStore state machine: ANISTS non-blocking +
DEGRADED_STANDBY -> STANDBY_TO_ACTIVE
- Map ACTIVE_NOT_IN_SYNC_TO_STANDBY to ClusterRole ACTIVE (non-blocking);
only
ACTIVE_IN_SYNC_TO_STANDBY remains mutation-blocking.
- Allow DEGRADED_STANDBY -> STANDBY_TO_ACTIVE so a degraded standby can
promote on failover.
- Tests: HAGroupStoreRecordTest role/mutation-block and transition
assertions; HAGroupStoreManagerIT
multi-group blocking uses ACTIVE_IN_SYNC_TO_STANDBY.
Co-authored-by: Cursor <[email protected]>
* PHOENIX-7566 Lock down DEGRADED_STANDBY allowed transition set in
HAGroupStoreRecordTest
Add assertFalse coverage for transitions outside DEGRADED_STANDBY's allowed
set {STANDBY, STANDBY_TO_ACTIVE} (ACTIVE_IN_SYNC, OFFLINE) so the test pins
both the allowed and disallowed transitions. Addresses PR review nit.
Co-authored-by: Cursor <[email protected]>
---------
Co-authored-by: Ritesh Garg
<[email protected]>
Co-authored-by: Cursor <[email protected]>
---
.../org/apache/phoenix/jdbc/HAGroupStoreRecord.java | 4 ++--
.../apache/phoenix/jdbc/HAGroupStoreManagerIT.java | 7 ++++---
.../apache/phoenix/jdbc/HAGroupStoreRecordTest.java | 21 ++++++++++++++++++++-
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/HAGroupStoreRecord.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/HAGroupStoreRecord.java
index da35da13dd..b72cc39b1c 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/HAGroupStoreRecord.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/HAGroupStoreRecord.java
@@ -76,11 +76,11 @@ public class HAGroupStoreRecord {
case ABORT_TO_ACTIVE_NOT_IN_SYNC:
case ACTIVE_IN_SYNC:
case ACTIVE_NOT_IN_SYNC:
+ case ACTIVE_NOT_IN_SYNC_TO_STANDBY:
case ACTIVE_NOT_IN_SYNC_WITH_OFFLINE_PEER:
case ACTIVE_WITH_OFFLINE_PEER:
return ClusterRoleRecord.ClusterRole.ACTIVE;
case ACTIVE_IN_SYNC_TO_STANDBY:
- case ACTIVE_NOT_IN_SYNC_TO_STANDBY:
return ClusterRoleRecord.ClusterRole.ACTIVE_TO_STANDBY;
case ABORT_TO_STANDBY:
case DEGRADED_STANDBY:
@@ -114,7 +114,7 @@ public class HAGroupStoreRecord {
ACTIVE_IN_SYNC_TO_STANDBY.allowedTransitions =
ImmutableSet.of(ABORT_TO_ACTIVE_IN_SYNC, STANDBY);
STANDBY_TO_ACTIVE.allowedTransitions = ImmutableSet.of(ABORT_TO_STANDBY,
ACTIVE_IN_SYNC);
- DEGRADED_STANDBY.allowedTransitions = ImmutableSet.of(STANDBY);
+ DEGRADED_STANDBY.allowedTransitions = ImmutableSet.of(STANDBY,
STANDBY_TO_ACTIVE);
ACTIVE_WITH_OFFLINE_PEER.allowedTransitions =
ImmutableSet.of(ACTIVE_NOT_IN_SYNC);
ABORT_TO_ACTIVE_IN_SYNC.allowedTransitions =
ImmutableSet.of(ACTIVE_IN_SYNC);
ABORT_TO_ACTIVE_NOT_IN_SYNC.allowedTransitions =
ImmutableSet.of(ACTIVE_NOT_IN_SYNC);
diff --git
a/phoenix-core/src/it/java/org/apache/phoenix/jdbc/HAGroupStoreManagerIT.java
b/phoenix-core/src/it/java/org/apache/phoenix/jdbc/HAGroupStoreManagerIT.java
index b0ce7f2655..f2697ae719 100644
---
a/phoenix-core/src/it/java/org/apache/phoenix/jdbc/HAGroupStoreManagerIT.java
+++
b/phoenix-core/src/it/java/org/apache/phoenix/jdbc/HAGroupStoreManagerIT.java
@@ -145,16 +145,17 @@ public class HAGroupStoreManagerIT extends HABaseIT {
assertFalse(haGroupStoreManager.isMutationBlocked(haGroupName1));
assertFalse(haGroupStoreManager.isMutationBlocked(haGroupName2));
- // Update only second group to ACTIVE_NOT_IN_SYNC_TO_STANDBY
+ // Move only the second group into a mutation-blocking drain state
+ // (ACTIVE_IN_SYNC_TO_STANDBY maps to ACTIVE_TO_STANDBY, which blocks
mutations).
HAGroupStoreRecord transitionRecord2 = new HAGroupStoreRecord("1.0",
haGroupName2,
- HAGroupStoreRecord.HAGroupState.ACTIVE_NOT_IN_SYNC_TO_STANDBY, 0L,
+ HAGroupStoreRecord.HAGroupState.ACTIVE_IN_SYNC_TO_STANDBY, 0L,
HighAvailabilityPolicy.FAILOVER.toString(), this.peerZKUrl,
CLUSTERS.getMasterAddress1(),
CLUSTERS.getMasterAddress2(), CLUSTERS.getHdfsUrl1(),
CLUSTERS.getHdfsUrl2(), 0L);
haAdmin.updateHAGroupStoreRecordInZooKeeper(haGroupName2,
transitionRecord2, 0);
Thread.sleep(ZK_CURATOR_EVENT_PROPAGATION_TIMEOUT_MS);
- // Global mutations should be blocked due to second group
+ // Blocking is per-group: only the second group is blocked; the first
stays writable.
assertFalse(haGroupStoreManager.isMutationBlocked(haGroupName1));
assertTrue(haGroupStoreManager.isMutationBlocked(haGroupName2));
}
diff --git
a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/HAGroupStoreRecordTest.java
b/phoenix-core/src/test/java/org/apache/phoenix/jdbc/HAGroupStoreRecordTest.java
index 44216ef948..7a46698670 100644
---
a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/HAGroupStoreRecordTest.java
+++
b/phoenix-core/src/test/java/org/apache/phoenix/jdbc/HAGroupStoreRecordTest.java
@@ -239,7 +239,7 @@ public class HAGroupStoreRecordTest {
HAGroupStoreRecord.HAGroupState.ACTIVE_IN_SYNC.getClusterRole());
assertEquals(ClusterRoleRecord.ClusterRole.ACTIVE,
HAGroupStoreRecord.HAGroupState.ACTIVE_NOT_IN_SYNC.getClusterRole());
- assertEquals(ClusterRoleRecord.ClusterRole.ACTIVE_TO_STANDBY,
+ assertEquals(ClusterRoleRecord.ClusterRole.ACTIVE,
HAGroupStoreRecord.HAGroupState.ACTIVE_NOT_IN_SYNC_TO_STANDBY.getClusterRole());
assertEquals(ClusterRoleRecord.ClusterRole.ACTIVE,
HAGroupStoreRecord.HAGroupState.ACTIVE_NOT_IN_SYNC_WITH_OFFLINE_PEER.getClusterRole());
@@ -257,6 +257,12 @@ public class HAGroupStoreRecordTest {
HAGroupStoreRecord.HAGroupState.STANDBY_TO_ACTIVE.getClusterRole());
assertEquals(ClusterRoleRecord.ClusterRole.UNKNOWN,
HAGroupStoreRecord.HAGroupState.UNKNOWN.getClusterRole());
+
+ // ANISTS is non-blocking (maps to ACTIVE); only AISTS blocks mutations.
+
assertFalse(HAGroupStoreRecord.HAGroupState.ACTIVE_NOT_IN_SYNC_TO_STANDBY.getClusterRole()
+ .isMutationBlocked());
+
assertTrue(HAGroupStoreRecord.HAGroupState.ACTIVE_IN_SYNC_TO_STANDBY.getClusterRole()
+ .isMutationBlocked());
}
@Test
@@ -294,6 +300,12 @@ public class HAGroupStoreRecordTest {
.isTransitionAllowed(HAGroupStoreRecord.HAGroupState.ABORT_TO_STANDBY));
assertTrue(HAGroupStoreRecord.HAGroupState.STANDBY_TO_ACTIVE
.isTransitionAllowed(HAGroupStoreRecord.HAGroupState.ACTIVE_IN_SYNC));
+
+ // A degraded standby can recover to STANDBY or promote directly on
failover.
+ assertTrue(HAGroupStoreRecord.HAGroupState.DEGRADED_STANDBY
+ .isTransitionAllowed(HAGroupStoreRecord.HAGroupState.STANDBY));
+ assertTrue(HAGroupStoreRecord.HAGroupState.DEGRADED_STANDBY
+ .isTransitionAllowed(HAGroupStoreRecord.HAGroupState.STANDBY_TO_ACTIVE));
}
@Test
@@ -321,6 +333,13 @@ public class HAGroupStoreRecordTest {
.isTransitionAllowed(HAGroupStoreRecord.HAGroupState.STANDBY));
assertFalse(HAGroupStoreRecord.HAGroupState.UNKNOWN
.isTransitionAllowed(HAGroupStoreRecord.HAGroupState.OFFLINE));
+
+ // A degraded standby's allowed set is exactly {STANDBY,
STANDBY_TO_ACTIVE}; it must promote
+ // via STANDBY_TO_ACTIVE and cannot jump directly to an active or offline
state.
+ assertFalse(HAGroupStoreRecord.HAGroupState.DEGRADED_STANDBY
+ .isTransitionAllowed(HAGroupStoreRecord.HAGroupState.ACTIVE_IN_SYNC));
+ assertFalse(HAGroupStoreRecord.HAGroupState.DEGRADED_STANDBY
+ .isTransitionAllowed(HAGroupStoreRecord.HAGroupState.OFFLINE));
}
@Test