This is an automated email from the ASF dual-hosted git repository.
yongzao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 9d474682cf5 Enhance "remove region" sql to handle the case of DataNode
not exist (#15728)
9d474682cf5 is described below
commit 9d474682cf583f77ccb70be13bce41968e88d0ab
Author: Li Yu Heng <[email protected]>
AuthorDate: Tue Jun 17 09:50:09 2025 +0800
Enhance "remove region" sql to handle the case of DataNode not exist
(#15728)
---
.../iotdb/confignode/manager/ProcedureManager.java | 42 +++++++++++++++++-----
.../partition/DatabasePartitionTable.java | 10 +++---
.../persistence/partition/PartitionInfo.java | 2 +-
.../persistence/partition/RegionGroup.java | 6 ++--
4 files changed, 44 insertions(+), 16 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 e257ff5669c..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;
@@ -161,6 +162,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -837,15 +839,13 @@ public class ProcedureManager {
private TSStatus checkRemoveRegion(
TRemoveRegionReq req,
TConsensusGroupId regionId,
- TDataNodeLocation targetDataNode,
+ @Nullable TDataNodeLocation targetDataNode,
TDataNodeLocation coordinator) {
String failMessage =
regionOperationCommonCheck(
regionId,
targetDataNode,
- Arrays.asList(
- new Pair<>("Target DataNode", targetDataNode),
- 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 (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);
}