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

jackietien 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 7bbf27df0ac Make show-queries can execute on more status node
7bbf27df0ac is described below

commit 7bbf27df0ac5cdb064a379cdf819d4a1adce8bf6
Author: Weihao Li <[email protected]>
AuthorDate: Mon Jan 6 14:02:05 2025 +0800

    Make show-queries can execute on more status node
---
 .../iotdb/confignode/manager/ConfigManager.java    |  4 +--
 .../apache/iotdb/confignode/manager/IManager.java  |  2 +-
 .../iotdb/confignode/manager/load/LoadManager.java | 11 ++++++
 .../confignode/manager/load/cache/LoadCache.java   | 17 +++++++++
 .../iotdb/confignode/manager/node/NodeManager.java | 13 +++++++
 .../thrift/ConfigNodeRPCServiceProcessor.java      |  4 +--
 .../iotdb/db/protocol/client/ConfigNodeClient.java |  4 +--
 .../db/queryengine/plan/analyze/Analysis.java      | 10 +++---
 .../queryengine/plan/analyze/AnalyzeVisitor.java   | 31 +++--------------
 .../plan/planner/LogicalPlanBuilder.java           |  2 +-
 .../DataNodeLocationSupplierFactory.java           | 40 +++++++++++-----------
 .../apache/iotdb/commons/cluster/NodeStatus.java   | 13 +++++++
 .../src/main/thrift/confignode.thrift              |  4 +--
 13 files changed, 94 insertions(+), 61 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index d1006aaba6f..432784737c7 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -1755,12 +1755,12 @@ public class ConfigManager implements IManager {
   }
 
   @Override
-  public TGetDataNodeLocationsResp getRunningDataNodeLocations() {
+  public TGetDataNodeLocationsResp getReadableDataNodeLocations() {
     TSStatus status = confirmLeader();
     return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()
         ? new TGetDataNodeLocationsResp(
             new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()),
-            
nodeManager.filterDataNodeThroughStatus(NodeStatus.Running).stream()
+            
nodeManager.filterDataNodeThroughStatus(NodeStatus::isReadable).stream()
                 .map(TDataNodeConfiguration::getLocation)
                 .collect(Collectors.toList()))
         : new TGetDataNodeLocationsResp(status, Collections.emptyList());
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
index 779f3daa03b..cae5fe9c956 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
@@ -589,7 +589,7 @@ public interface IManager {
 
   TSStatus killQuery(String queryId, int dataNodeId);
 
-  TGetDataNodeLocationsResp getRunningDataNodeLocations();
+  TGetDataNodeLocationsResp getReadableDataNodeLocations();
 
   /**
    * Get the latest RegionRouteMap.
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/LoadManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/LoadManager.java
index 835f92a302e..921dd2cd9ae 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/LoadManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/LoadManager.java
@@ -50,6 +50,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TTimeSlotList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 
 /**
  * The {@link LoadManager} at ConfigNodeGroup-Leader is active. It proactively 
implements the
@@ -209,6 +210,16 @@ public class LoadManager {
     return loadCache.filterDataNodeThroughStatus(status);
   }
 
+  /**
+   * Filter DataNodes through the NodeStatus predicate.
+   *
+   * @param statusPredicate The NodeStatus predicate
+   * @return Filtered DataNodes with the predicate
+   */
+  public List<Integer> filterDataNodeThroughStatus(Function<NodeStatus, 
Boolean> statusPredicate) {
+    return loadCache.filterDataNodeThroughStatus(statusPredicate);
+  }
+
   /**
    * Get the free disk space of the specified DataNode.
    *
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/cache/LoadCache.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/cache/LoadCache.java
index e1080b94740..fec21f30a27 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/cache/LoadCache.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/load/cache/LoadCache.java
@@ -63,6 +63,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /** Maintain all kinds of heartbeat samples and statistics. */
@@ -541,6 +542,22 @@ public class LoadCache {
         .collect(Collectors.toList());
   }
 
+  /**
+   * Filter DataNodes through the NodeStatus predicate.
+   *
+   * @param statusPredicate The NodeStatus predicate
+   * @return Filtered DataNodes with the predicate
+   */
+  public List<Integer> filterDataNodeThroughStatus(Function<NodeStatus, 
Boolean> statusPredicate) {
+    return nodeCacheMap.entrySet().stream()
+        .filter(
+            nodeCacheEntry ->
+                nodeCacheEntry.getValue() instanceof DataNodeHeartbeatCache
+                    && 
statusPredicate.apply(nodeCacheEntry.getValue().getNodeStatus()))
+        .map(Map.Entry::getKey)
+        .collect(Collectors.toList());
+  }
+
   /**
    * Get the free disk space of the specified DataNode.
    *
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
index ecdb8e4ba45..3bdfcb35fef 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/node/NodeManager.java
@@ -112,6 +112,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /** {@link NodeManager} manages cluster node addition and removal requests. */
@@ -1081,6 +1082,18 @@ public class NodeManager {
     return 
nodeInfo.getRegisteredDataNodes(getLoadManager().filterDataNodeThroughStatus(status));
   }
 
+  /**
+   * Filter DataNodes through the NodeStatus predicate.
+   *
+   * @param statusPredicate The NodeStatus predicate
+   * @return Filtered DataNodes with the predicate
+   */
+  public List<TDataNodeConfiguration> filterDataNodeThroughStatus(
+      Function<NodeStatus, Boolean> statusPredicate) {
+    return nodeInfo.getRegisteredDataNodes(
+        getLoadManager().filterDataNodeThroughStatus(statusPredicate));
+  }
+
   /**
    * Get the DataNodeLocation of the DataNode which has the lowest loadScore.
    *
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
index ecfe6455d4b..5d3de28a26a 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
@@ -979,8 +979,8 @@ public class ConfigNodeRPCServiceProcessor implements 
IConfigNodeRPCService.Ifac
   }
 
   @Override
-  public TGetDataNodeLocationsResp getRunningDataNodeLocations() {
-    return configManager.getRunningDataNodeLocations();
+  public TGetDataNodeLocationsResp getReadableDataNodeLocations() {
+    return configManager.getReadableDataNodeLocations();
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
index a3ff327e9ef..8854c0df3c5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
@@ -807,9 +807,9 @@ public class ConfigNodeClient implements 
IConfigNodeRPCService.Iface, ThriftClie
   }
 
   @Override
-  public TGetDataNodeLocationsResp getRunningDataNodeLocations() throws 
TException {
+  public TGetDataNodeLocationsResp getReadableDataNodeLocations() throws 
TException {
     return executeRemoteCallWithRetry(
-        () -> client.getRunningDataNodeLocations(), resp -> 
!updateConfigNodeLeader(resp.status));
+        () -> client.getReadableDataNodeLocations(), resp -> 
!updateConfigNodeLeader(resp.status));
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
index 770b20ebcf5..feff3610691 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
@@ -286,7 +286,7 @@ public class Analysis implements IAnalysis {
   
/////////////////////////////////////////////////////////////////////////////////////////////////
 
   // extra message from config node, queries wll be sent to these Running 
DataNodes
-  private List<TDataNodeLocation> runningDataNodeLocations;
+  private List<TDataNodeLocation> readableDataNodeLocations;
 
   // used for limit and offset push down optimizer, if we select all columns 
from aligned device, we
   // can use statistics to skip
@@ -805,12 +805,12 @@ public class Analysis implements IAnalysis {
     this.tagValuesToGroupedTimeseriesOperands = 
tagValuesToGroupedTimeseriesOperands;
   }
 
-  public List<TDataNodeLocation> getRunningDataNodeLocations() {
-    return runningDataNodeLocations;
+  public List<TDataNodeLocation> getReadableDataNodeLocations() {
+    return readableDataNodeLocations;
   }
 
-  public void setRunningDataNodeLocations(List<TDataNodeLocation> 
runningDataNodeLocations) {
-    this.runningDataNodeLocations = runningDataNodeLocations;
+  public void setReadableDataNodeLocations(List<TDataNodeLocation> 
readableDataNodeLocations) {
+    this.readableDataNodeLocations = readableDataNodeLocations;
   }
 
   public boolean isVirtualSource() {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
index 22686dc3e15..e97ecd32d40 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeVisitor.java
@@ -22,7 +22,6 @@ package org.apache.iotdb.db.queryengine.plan.analyze;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
-import org.apache.iotdb.commons.client.exception.ClientManagerException;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
@@ -40,7 +39,6 @@ import 
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
 import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
 import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
 import org.apache.iotdb.commons.utils.TimePartitionUtils;
-import org.apache.iotdb.confignode.rpc.thrift.TGetDataNodeLocationsResp;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.ainode.GetModelInfoException;
@@ -48,9 +46,6 @@ import 
org.apache.iotdb.db.exception.metadata.template.TemplateIncompatibleExcep
 import org.apache.iotdb.db.exception.metadata.view.UnsupportedViewException;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
-import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
-import org.apache.iotdb.db.protocol.client.ConfigNodeClientManager;
-import org.apache.iotdb.db.protocol.client.ConfigNodeInfo;
 import org.apache.iotdb.db.queryengine.common.DeviceContext;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.TimeseriesContext;
@@ -165,7 +160,6 @@ import org.apache.iotdb.db.utils.constant.SqlConstant;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 
-import org.apache.thrift.TException;
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.read.common.TimeRange;
@@ -222,6 +216,7 @@ import static 
org.apache.iotdb.db.queryengine.plan.analyze.SelectIntoUtils.const
 import static 
org.apache.iotdb.db.queryengine.plan.optimization.LimitOffsetPushDown.canPushDownLimitOffsetInGroupByTimeForDevice;
 import static 
org.apache.iotdb.db.queryengine.plan.optimization.LimitOffsetPushDown.pushDownLimitOffsetInGroupByTimeForDevice;
 import static 
org.apache.iotdb.db.queryengine.plan.parser.ASTVisitor.parseNodeString;
+import static 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.DataNodeLocationSupplierFactory.getReadableDataNodeLocations;
 import static 
org.apache.iotdb.db.schemaengine.schemaregion.view.visitor.GetSourcePathsVisitor.getSourcePaths;
 import static 
org.apache.iotdb.db.storageengine.load.metrics.LoadTsFileCostMetricsSet.ANALYSIS;
 import static org.apache.iotdb.db.utils.constant.SqlConstant.COUNT_TIME_HEADER;
@@ -3751,15 +3746,15 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
     analysis.setRespDatasetHeader(DatasetHeaderFactory.getShowQueriesHeader());
     analysis.setVirtualSource(true);
 
-    List<TDataNodeLocation> allRunningDataNodeLocations = 
getRunningDataNodeLocations();
-    if (allRunningDataNodeLocations.isEmpty()) {
+    List<TDataNodeLocation> allReadableDataNodeLocations = 
getReadableDataNodeLocations();
+    if (allReadableDataNodeLocations.isEmpty()) {
       analysis.setFinishQueryAfterAnalyze(true);
     }
     // TODO Constant folding optimization for Where Predicate after True/False 
Constant introduced
-    if (allRunningDataNodeLocations.isEmpty()) {
+    if (allReadableDataNodeLocations.isEmpty()) {
       throw new StatementAnalyzeException("no Running DataNodes");
     }
-    analysis.setRunningDataNodeLocations(allRunningDataNodeLocations);
+    analysis.setReadableDataNodeLocations(allReadableDataNodeLocations);
 
     Set<Expression> sourceExpressions = new HashSet<>();
     for (ColumnHeader columnHeader : 
analysis.getRespDatasetHeader().getColumnHeaders()) {
@@ -3777,22 +3772,6 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
     return analysis;
   }
 
-  private List<TDataNodeLocation> getRunningDataNodeLocations() {
-    try (ConfigNodeClient client =
-        
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID))
 {
-      TGetDataNodeLocationsResp showDataNodesResp = 
client.getRunningDataNodeLocations();
-      if (showDataNodesResp.getStatus().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-        throw new StatementAnalyzeException(
-            "An error occurred when executing getRunningDataNodeLocations():"
-                + showDataNodesResp.getStatus().getMessage());
-      }
-      return showDataNodesResp.getDataNodeLocationList();
-    } catch (ClientManagerException | TException e) {
-      throw new StatementAnalyzeException(
-          "An error occurred when executing getRunningDataNodeLocations():" + 
e.getMessage());
-    }
-  }
-
   private void analyzeWhere(Analysis analysis, ShowQueriesStatement 
showQueriesStatement) {
     WhereCondition whereCondition = showQueriesStatement.getWhereCondition();
     if (whereCondition == null) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
index caa72292730..c68c0ef4d74 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
@@ -1271,7 +1271,7 @@ public class LogicalPlanBuilder {
   }
 
   public LogicalPlanBuilder planShowQueries(Analysis analysis) {
-    List<TDataNodeLocation> dataNodeLocations = 
analysis.getRunningDataNodeLocations();
+    List<TDataNodeLocation> dataNodeLocations = 
analysis.getReadableDataNodeLocations();
     if (dataNodeLocations.size() == 1) {
       this.root =
           planSingleShowQueries(dataNodeLocations.get(0))
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
index 2c33d30f8f5..1d21d91e429 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/DataNodeLocationSupplierFactory.java
@@ -46,6 +46,25 @@ public class DataNodeLocationSupplierFactory {
     List<TDataNodeLocation> getDataNodeLocations(String table);
   }
 
+  /** DataNode in these states is readable: Running, ReadOnly, Removing */
+  public static List<TDataNodeLocation> getReadableDataNodeLocations() {
+    try (final ConfigNodeClient client =
+        
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID))
 {
+      final TGetDataNodeLocationsResp showDataNodesResp = 
client.getReadableDataNodeLocations();
+      if (showDataNodesResp.getStatus().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+        throw new IoTDBRuntimeException(
+            "An error occurred when executing getReadableDataNodeLocations():"
+                + showDataNodesResp.getStatus().getMessage(),
+            QUERY_PROCESS_ERROR.getStatusCode());
+      }
+      return showDataNodesResp.getDataNodeLocationList();
+    } catch (final ClientManagerException | TException e) {
+      throw new IoTDBRuntimeException(
+          "An error occurred when executing getReadableDataNodeLocations():" + 
e.getMessage(),
+          QUERY_PROCESS_ERROR.getStatusCode());
+    }
+  }
+
   private static class InformationSchemaTableDataNodeLocationSupplier
       implements DataNodeLocationSupplier {
     private InformationSchemaTableDataNodeLocationSupplier() {}
@@ -59,29 +78,10 @@ public class DataNodeLocationSupplierFactory {
       return SingletonHolder.INSTANCE;
     }
 
-    private List<TDataNodeLocation> getRunningDataNodeLocations() {
-      try (final ConfigNodeClient client =
-          
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID))
 {
-        final TGetDataNodeLocationsResp showDataNodesResp = 
client.getRunningDataNodeLocations();
-        if (showDataNodesResp.getStatus().getCode()
-            != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-          throw new IoTDBRuntimeException(
-              "An error occurred when executing getRunningDataNodeLocations():"
-                  + showDataNodesResp.getStatus().getMessage(),
-              QUERY_PROCESS_ERROR.getStatusCode());
-        }
-        return showDataNodesResp.getDataNodeLocationList();
-      } catch (final ClientManagerException | TException e) {
-        throw new IoTDBRuntimeException(
-            "An error occurred when executing getRunningDataNodeLocations():" 
+ e.getMessage(),
-            QUERY_PROCESS_ERROR.getStatusCode());
-      }
-    }
-
     @Override
     public List<TDataNodeLocation> getDataNodeLocations(final String 
tableName) {
       if (tableName.equals(InformationSchema.QUERIES)) {
-        return getRunningDataNodeLocations();
+        return getReadableDataNodeLocations();
       } else {
         throw new UnsupportedOperationException("Unknown table: " + tableName);
       }
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/cluster/NodeStatus.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/cluster/NodeStatus.java
index 32f083dd042..ac69a2901a0 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/cluster/NodeStatus.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/cluster/NodeStatus.java
@@ -57,4 +57,17 @@ public enum NodeStatus {
     // Currently, the only normal status is Running
     return status != null && status.equals(NodeStatus.Running);
   }
+
+  public static boolean isReadable(NodeStatus status) {
+    switch (status) {
+      case Running:
+      case Removing:
+      case ReadOnly:
+        return true;
+      case Unknown:
+        return false;
+      default:
+        throw new UnsupportedOperationException(String.format("Unknown 
NodeStatus %s.", status));
+    }
+  }
 }
diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift 
b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
index f2e6c140091..7d8d22a0a3a 100644
--- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
@@ -1550,8 +1550,8 @@ service IConfigNodeRPCService {
   /** Kill query */
   common.TSStatus killQuery(string queryId, i32 dataNodeId)
 
-  /** Get all DataNodeLocations of Running DataNodes */
-  TGetDataNodeLocationsResp getRunningDataNodeLocations()
+  /** Get all DataNodeLocations of Readable DataNodes */
+  TGetDataNodeLocationsResp getReadableDataNodeLocations()
 
   // ======================================================
   // Cluster Tools

Reply via email to