You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by su...@apache.org on 2026/02/04 18:47:47 UTC

(ozone) branch master updated: HDDS-14551. Don't update container state when replica sequence doesn't match with container seq id. (#9701)

This is an automated email from the ASF dual-hosted git repository.

sumitagrawal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 7d3a7cd9504 HDDS-14551. Don't update container state when replica sequence doesn't match with container seq id. (#9701)
7d3a7cd9504 is described below

commit 7d3a7cd9504f25478b01287a080580aea5ea7705
Author: Ashish Kumar <11...@users.noreply.github.com>
AuthorDate: Thu Feb 5 00:17:41 2026 +0530

    HDDS-14551. Don't update container state when replica sequence doesn't match with container seq id. (#9701)
---
 .../replication/health/EmptyContainerHandler.java  |  7 ++++
 .../health/TestEmptyContainerHandler.java          | 37 ++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/health/EmptyContainerHandler.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/health/EmptyContainerHandler.java
index e955193e683..8fa72cbc50f 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/health/EmptyContainerHandler.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/health/EmptyContainerHandler.java
@@ -63,6 +63,13 @@ public boolean handle(ContainerCheckRequest request) {
         // delete replicas if they are closed and empty
         deleteContainerReplicas(containerInfo, replicas);
 
+        if (containerInfo.getReplicationType() == HddsProtos.ReplicationType.RATIS) {
+          if (replicas.stream().filter(r -> r.getSequenceId() != null)
+              .noneMatch(r -> r.getSequenceId() == containerInfo.getSequenceId())) {
+            // don't update container state if replica seqid don't match with container seq id
+            return true;
+          }
+        }
         // Update the container's state
         replicationManager.updateContainerState(
             containerInfo.containerID(), HddsProtos.LifeCycleEvent.DELETE);
diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestEmptyContainerHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestEmptyContainerHandler.java
index 92c0b0fde06..4811a9651c4 100644
--- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestEmptyContainerHandler.java
+++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestEmptyContainerHandler.java
@@ -20,6 +20,7 @@
 import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState.CLOSED;
 import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState.CLOSING;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.eq;
@@ -247,6 +248,42 @@ public void testEmptyECContainerWithNonEmptyReplicaReturnsFalse()
     assertAndVerify(request, false, 0, 0);
   }
 
+  /**
+   * Tests that container state is NOT updated to DELETE when no replica
+   * has a matching sequence ID with the container.
+   */
+  @Test
+  public void testNoUpdateContainerStateWhenReplicaSequenceIdDoesNotMatch()
+      throws IOException {
+    long keyCount = 0L;
+    long bytesUsed = 0L;
+    long containerSequenceId = 100L;
+    // Create container with specific sequence ID
+    ContainerInfo containerInfo = ReplicationTestUtil.createContainerInfo(
+        ratisReplicationConfig, 1, CLOSED, containerSequenceId);
+    // Create replicas - all with 0 sequence IDs (none matching container)
+    Set<ContainerReplica> containerReplicas = ReplicationTestUtil
+        .createReplicas(containerInfo.containerID(),
+            ContainerReplicaProto.State.CLOSED, keyCount, bytesUsed,
+            0, 0, 0);
+    ContainerCheckRequest request = new ContainerCheckRequest.Builder()
+        .setPendingOps(Collections.emptyList())
+        .setReport(new ReplicationManagerReport(rmConf.getContainerSampleLimit()))
+        .setContainerInfo(containerInfo)
+        .setContainerReplicas(containerReplicas)
+        .build();
+    // Handler should return true but NOT update container state
+    // because no replica has matching sequence ID
+    assertTrue(emptyContainerHandler.handle(request));
+    verify(replicationManager, times(3)).sendDeleteCommand(
+        any(ContainerInfo.class), anyInt(),
+        any(DatanodeDetails.class), eq(false));
+    // updateContainerState should NOT be called when sequence IDs don't match
+    verify(replicationManager, times(0)).updateContainerState(
+        any(ContainerID.class),
+        any(HddsProtos.LifeCycleEvent.class));
+  }
+
   /**
    * Asserts that handler returns the specified assertion and delete command
    * to replicas is sent the specified number of times.


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org