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

Reply via email to