diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/AbstractContainerReportHandler.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/AbstractContainerReportHandler.java index f79507e1e66..6028bbfd90e 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/AbstractContainerReportHandler.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/AbstractContainerReportHandler.java @@ -313,6 +313,11 @@ private boolean updateContainerState(final DatanodeDetails datanode, deleteReplica(containerId, datanode, publisher, "DELETED", false, detailsForLogging); return false; } + if (container.getReplicationType().equals(HddsProtos.ReplicationType.EC)) { + // In case of EC container, delete its replica to avoid orphan replica + deleteReplica(containerId, datanode, publisher, "DELETED", true, detailsForLogging); + return false; + } // HDDS-12421: fall-through to case DELETING case DELETING: // HDDS-11136: If a DELETING container has a non-empty CLOSED replica, transition the container to CLOSED diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerReportHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerReportHandler.java index 0e8eee799bc..264a429960f 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerReportHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerReportHandler.java @@ -209,6 +209,10 @@ static Stream containerAndReplicaStates() { containerState.equals(HddsProtos.LifeCycleState.DELETING))) { continue; } + if (replicationType == HddsProtos.ReplicationType.EC && + containerState.equals(HddsProtos.LifeCycleState.DELETED)) { + continue; + } for (ContainerReplicaProto.State invalidState : invalidReplicaStates) { combinations.add(Arguments.of(replicationType, containerState, replicaState, invalidState)); } diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerStateManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerStateManager.java index 869b7dd5bb9..dfb4f38deef 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerStateManager.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/TestContainerStateManager.java @@ -301,9 +301,8 @@ public void testDeletedContainerWithLowerBcsidStaleReplicaRatis() } /** - * DELETED EC container + CLOSED replica with BCSID <= container seqId. - * Expected: Should NOT send force delete - * Should transition to CLOSED instead + * DELETED EC container in SCM. + * Expected: Should send force delete to DN */ @Test public void testDeletedECContainerWithStaleClosedReplicaShouldNotForceDelete() @@ -318,11 +317,12 @@ public void testDeletedECContainerWithStaleClosedReplicaShouldNotForceDelete() repConfig); containerStateManager.addContainer(ecContainer.getProtobuf()); assertEquals(HddsProtos.ReplicationType.EC, ecContainer.getReplicationType()); - // Report CLOSED replica with BCSID = container's seqId + + // Verify delete command sent sendReportAndCaptureDeleteCommand(ecContainer, datanode, - ecContainer.getSequenceId(), false, 1, false); - // Container should transition to CLOSED - verifyContainerState(ecContainer.containerID(), HddsProtos.LifeCycleState.CLOSED); + ecContainer.getSequenceId(), false, 1, true); + // Container should remain as DELETED + verifyContainerState(ecContainer.containerID(), HddsProtos.LifeCycleState.DELETED); } private DeleteContainerCommand sendReportAndCaptureDeleteCommand(