2424import org .apache .iotdb .common .rpc .thrift .TConsensusGroupType ;
2525import org .apache .iotdb .common .rpc .thrift .TDataNodeConfiguration ;
2626import org .apache .iotdb .common .rpc .thrift .TDataNodeLocation ;
27+ import org .apache .iotdb .common .rpc .thrift .TEndPoint ;
2728import org .apache .iotdb .common .rpc .thrift .TSStatus ;
2829import org .apache .iotdb .commons .cluster .NodeStatus ;
2930import org .apache .iotdb .commons .conf .CommonConfig ;
161162import org .slf4j .LoggerFactory ;
162163
163164import javax .annotation .Nonnull ;
165+ import javax .annotation .Nullable ;
164166
165167import java .io .IOException ;
166168import java .nio .ByteBuffer ;
@@ -837,15 +839,13 @@ private TSStatus checkExtendRegion(
837839 private TSStatus checkRemoveRegion (
838840 TRemoveRegionReq req ,
839841 TConsensusGroupId regionId ,
840- TDataNodeLocation targetDataNode ,
842+ @ Nullable TDataNodeLocation targetDataNode ,
841843 TDataNodeLocation coordinator ) {
842844 String failMessage =
843845 regionOperationCommonCheck (
844846 regionId ,
845847 targetDataNode ,
846- Arrays .asList (
847- new Pair <>("Target DataNode" , targetDataNode ),
848- new Pair <>("Coordinator" , coordinator )),
848+ Arrays .asList (new Pair <>("Coordinator" , coordinator )),
849849 req .getModel ());
850850
851851 if (configManager
@@ -855,11 +855,12 @@ private TSStatus checkRemoveRegion(
855855 .getDataNodeLocationsSize ()
856856 == 1 ) {
857857 failMessage = String .format ("%s only has 1 replica, it cannot be removed" , regionId );
858- } else if (configManager
859- .getPartitionManager ()
860- .getAllReplicaSets (targetDataNode .getDataNodeId ())
861- .stream ()
862- .noneMatch (replicaSet -> replicaSet .getRegionId ().equals (regionId ))) {
858+ } else if (targetDataNode != null
859+ && configManager
860+ .getPartitionManager ()
861+ .getAllReplicaSets (targetDataNode .getDataNodeId ())
862+ .stream ()
863+ .noneMatch (replicaSet -> replicaSet .getRegionId ().equals (regionId ))) {
863864 failMessage =
864865 String .format (
865866 "Target DataNode %s doesn't contain Region %s" , req .getDataNodeId (), regionId );
@@ -1208,6 +1209,23 @@ public TSStatus removeRegion(TRemoveRegionReq req) {
12081209 return status ;
12091210 }
12101211
1212+ // SPECIAL CASE
1213+ if (targetDataNode == null ) {
1214+ // If targetDataNode is null, it means the target DataNode does not exist in the
1215+ // NodeManager.
1216+ // In this case, simply clean up the partition table once and do nothing else.
1217+ LOGGER .warn (
1218+ "Remove region: Target DataNode {} not found, will simply clean up the partition table of region {} and do nothing else." ,
1219+ req .getDataNodeId (),
1220+ req .getRegionId ());
1221+ this .executor
1222+ .getEnvironment ()
1223+ .getRegionMaintainHandler ()
1224+ .removeRegionLocation (
1225+ regionId , buildFakeDataNodeLocation (req .getDataNodeId (), "FakeIpForRemoveRegion" ));
1226+ return new TSStatus (TSStatusCode .SUCCESS_STATUS .getStatusCode ());
1227+ }
1228+
12111229 // submit procedure
12121230 RemoveRegionPeerProcedure procedure =
12131231 new RemoveRegionPeerProcedure (regionId , coordinator , targetDataNode );
@@ -1219,6 +1237,12 @@ public TSStatus removeRegion(TRemoveRegionReq req) {
12191237 }
12201238 }
12211239
1240+ private static TDataNodeLocation buildFakeDataNodeLocation (int dataNodeId , String message ) {
1241+ TEndPoint fakeEndPoint = new TEndPoint (message , -1 );
1242+ return new TDataNodeLocation (
1243+ dataNodeId , fakeEndPoint , fakeEndPoint , fakeEndPoint , fakeEndPoint , fakeEndPoint );
1244+ }
1245+
12221246 // endregion
12231247
12241248 /**
0 commit comments