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

liyuheng pushed a commit to branch lyh/improve-remove-region
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit e8948bf7b7564b7d9d21243b8268d0faf36ffa5a
Author: liyuheng <[email protected]>
AuthorDate: Mon Jun 16 18:10:35 2025 +0800

    seems done
---
 .../iotdb/confignode/manager/ProcedureManager.java | 38 ++++++++++++++++++----
 .../partition/DatabasePartitionTable.java          | 10 +++---
 .../persistence/partition/PartitionInfo.java       |  2 +-
 .../persistence/partition/RegionGroup.java         |  6 ++--
 4 files changed, 42 insertions(+), 14 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
index a97645244c2..61e0639b558 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId;
 import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeConfiguration;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.cluster.NodeStatus;
 import org.apache.iotdb.commons.conf.CommonConfig;
@@ -844,8 +845,7 @@ public class ProcedureManager {
         regionOperationCommonCheck(
             regionId,
             targetDataNode,
-            Arrays.asList(
-                new Pair<>("Coordinator", coordinator)),
+            Arrays.asList(new Pair<>("Coordinator", coordinator)),
             req.getModel());
 
     if (configManager
@@ -855,11 +855,12 @@ public class ProcedureManager {
             .getDataNodeLocationsSize()
         == 1) {
       failMessage = String.format("%s only has 1 replica, it cannot be 
removed", regionId);
-    } else if (targetDataNode != null && configManager
-        .getPartitionManager()
-        .getAllReplicaSets(targetDataNode.getDataNodeId())
-        .stream()
-        .noneMatch(replicaSet -> replicaSet.getRegionId().equals(regionId))) {
+    } else if (targetDataNode != null
+        && configManager
+            .getPartitionManager()
+            .getAllReplicaSets(targetDataNode.getDataNodeId())
+            .stream()
+            .noneMatch(replicaSet -> 
replicaSet.getRegionId().equals(regionId))) {
       failMessage =
           String.format(
               "Target DataNode %s doesn't contain Region %s", 
req.getDataNodeId(), regionId);
@@ -1208,6 +1209,23 @@ public class ProcedureManager {
         return status;
       }
 
+      // SPECIAL CASE
+      if (targetDataNode == null) {
+        // If targetDataNode is null, it means the target DataNode does not 
exist in the
+        // NodeManager.
+        // In this case, simply clean up the partition table once and do 
nothing else.
+        LOGGER.warn(
+            "Remove region: Target DataNode {} not found, will simply clean up 
the partition table of region {} and do nothing else.",
+            req.getDataNodeId(),
+            req.getRegionId());
+        this.executor
+            .getEnvironment()
+            .getRegionMaintainHandler()
+            .removeRegionLocation(
+                regionId, buildFakeDataNodeLocation(req.getDataNodeId(), 
"FakeIpForRemoveRegion"));
+        return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+      }
+
       // submit procedure
       RemoveRegionPeerProcedure procedure =
           new RemoveRegionPeerProcedure(regionId, coordinator, targetDataNode);
@@ -1219,6 +1237,12 @@ public class ProcedureManager {
     }
   }
 
+  private static TDataNodeLocation buildFakeDataNodeLocation(int dataNodeId, 
String message) {
+    TEndPoint fakeEndPoint = new TEndPoint(message, -1);
+    return new TDataNodeLocation(
+        dataNodeId, fakeEndPoint, fakeEndPoint, fakeEndPoint, fakeEndPoint, 
fakeEndPoint);
+  }
+
   // endregion
 
   /**
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/DatabasePartitionTable.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/DatabasePartitionTable.java
index 6544f1a7c7c..1d2d776c69b 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/DatabasePartitionTable.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/DatabasePartitionTable.java
@@ -539,7 +539,7 @@ public class DatabasePartitionTable {
     regionGroup.addRegionLocation(node);
   }
 
-  void removeRegionLocation(TConsensusGroupId regionId, TDataNodeLocation 
node) {
+  void removeRegionLocation(TConsensusGroupId regionId, int nodeId) {
     RegionGroup regionGroup = regionGroupMap.get(regionId);
     if (regionGroup == null) {
       LOGGER.warn(
@@ -548,16 +548,18 @@ public class DatabasePartitionTable {
           databaseName);
       return;
     }
-    if (!regionGroup.getReplicaSet().getDataNodeLocations().contains(node)) {
+    if (regionGroup.getReplicaSet().getDataNodeLocations().stream()
+        .map(TDataNodeLocation::getDataNodeId)
+        .noneMatch(id -> id == nodeId)) {
       LOGGER.info(
           "Node is not in region locations when removeRegionOldLocation in {}, 
"
               + "no need to remove it, node: {}, region: {}",
           databaseName,
-          node,
+          nodeId,
           regionId);
       return;
     }
-    regionGroup.removeRegionLocation(node);
+    regionGroup.removeRegionLocation(nodeId);
   }
 
   /**
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
index 3fd5adfea46..c85297764f9 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
@@ -620,7 +620,7 @@ public class PartitionInfo implements SnapshotProcessor {
         .forEach(
             databasePartitionTable ->
                 databasePartitionTable.removeRegionLocation(
-                    req.getRegionId(), req.getDeprecatedLocation()));
+                    req.getRegionId(), 
req.getDeprecatedLocation().getDataNodeId()));
     return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
   }
 
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/RegionGroup.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/RegionGroup.java
index 69143d8e287..6f9860b6bce 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/RegionGroup.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/RegionGroup.java
@@ -95,8 +95,10 @@ public class RegionGroup {
     replicaSet.getDataNodeLocations().sort(TDataNodeLocation::compareTo);
   }
 
-  public synchronized void removeRegionLocation(TDataNodeLocation node) {
-    replicaSet.getDataNodeLocations().remove(node);
+  public synchronized void removeRegionLocation(int nodeId) {
+    replicaSet
+        .getDataNodeLocations()
+        .removeIf(tDataNodeLocation -> nodeId == 
tDataNodeLocation.getDataNodeId());
     replicaSet.getDataNodeLocations().sort(TDataNodeLocation::compareTo);
   }
 

Reply via email to