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

qiaojialin 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 6536989d79 [IOTDB-3555] Show DataNodes tool (#6531)
6536989d79 is described below

commit 6536989d7967be9bfc054070ffedb58ebaae997c
Author: FangJL <[email protected]>
AuthorDate: Sat Jul 2 12:12:03 2022 +0800

    [IOTDB-3555] Show DataNodes tool (#6531)
---
 .../org/apache/iotdb/db/qp/sql/IdentifierParser.g4 |  1 +
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |  7 +-
 .../antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4  |  5 ++
 .../consensus/request/ConfigPhysicalPlanType.java  |  3 +-
 .../consensus/response/DataNodeInfosResp.java      | 11 +++
 .../iotdb/confignode/manager/ConfigManager.java    | 61 +++++++++++++++++
 .../apache/iotdb/confignode/manager/IManager.java  |  3 +
 .../iotdb/confignode/manager/NodeManager.java      | 24 ++++++-
 .../thrift/ConfigNodeRPCServiceProcessor.java      | 10 +++
 .../Maintenance-Tools/Maintenance-Command.md       | 55 +++++++++++++++
 .../Maintenance-Tools/Maintenance-Command.md       | 55 +++++++++++++++
 .../apache/iotdb/db/client/ConfigNodeClient.java   | 18 +++++
 .../iotdb/db/mpp/common/header/HeaderConstant.java | 20 ++++++
 .../plan/execution/config/ConfigTaskVisitor.java   |  7 ++
 .../plan/execution/config/ShowDataNodesTask.java   | 78 ++++++++++++++++++++++
 .../config/executor/ClusterConfigTaskExecutor.java | 23 +++++++
 .../config/executor/IConfigTaskExecutor.java       |  3 +
 .../executor/StandaloneConfigTaskExecutor.java     | 13 ++++
 .../iotdb/db/mpp/plan/parser/ASTVisitor.java       |  8 +++
 .../db/mpp/plan/statement/StatementVisitor.java    |  5 ++
 .../statement/metadata/ShowDataNodesStatement.java | 54 +++++++++++++++
 thrift-commons/src/main/thrift/common.thrift       |  9 +++
 .../src/main/thrift/confignode.thrift              | 10 +++
 23 files changed, 480 insertions(+), 3 deletions(-)

diff --git 
a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
index 4387f7c225..6cf23accb6 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
@@ -61,6 +61,7 @@ keyWords
     | CQS
     | CREATE
     | DATA
+    | DATANODES
     | DEBUG
     | DELETE
     | DESC
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index dd01a8e693..e64e5c8be3 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -43,7 +43,7 @@ ddlStatement
     | dropFunction | dropTrigger | dropContinuousQuery | dropSchemaTemplate
     | setTTL | unsetTTL | startTrigger | stopTrigger | setSchemaTemplate | 
unsetSchemaTemplate
     | showStorageGroup | showDevices | showTimeseries | showChildPaths | 
showChildNodes
-    | showFunctions | showTriggers | showContinuousQueries | showTTL | 
showAllTTL | showCluster | showRegion
+    | showFunctions | showTriggers | showContinuousQueries | showTTL | 
showAllTTL | showCluster | showRegion | showDataNodes
     | showSchemaTemplates | showNodesInSchemaTemplate
     | showPathsUsingSchemaTemplate | showPathsSetSchemaTemplate
     | countStorageGroup | countDevices | countTimeseries | countNodes
@@ -313,6 +313,11 @@ showRegion
     : SHOW (SCHEMA | DATA)? REGIONS
     ;
 
+// Show Data Nodes
+showDataNodes
+    : SHOW  DATANODES
+    ;
+
 // Show Schema Template
 showSchemaTemplates
     : SHOW SCHEMA? TEMPLATES
diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
index 307622686e..8fa766ac9b 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4
@@ -157,6 +157,11 @@ DATA
     : D A T A
     ;
 
+DATANODES
+
+    : D A T A N O D E S
+    ;
+
 DEBUG
     : D E B U G
     ;
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
index 0a9f458db1..6262e45dba 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanType.java
@@ -65,5 +65,6 @@ public enum ConfigPhysicalPlanType {
   CreateFunction,
   DropFunction,
   GetNodePathsPartition,
-  GetRegionInfoList;
+  GetRegionInfoList,
+  GetDataNodesInfoList;
 }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/DataNodeInfosResp.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/DataNodeInfosResp.java
index 7718d47131..a5f8ed3e96 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/DataNodeInfosResp.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/consensus/response/DataNodeInfosResp.java
@@ -19,17 +19,20 @@
 package org.apache.iotdb.confignode.consensus.response;
 
 import org.apache.iotdb.common.rpc.thrift.TDataNodeInfo;
+import org.apache.iotdb.common.rpc.thrift.TDataNodesInfo;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.confignode.rpc.thrift.TDataNodeInfoResp;
 import org.apache.iotdb.consensus.common.DataSet;
 import org.apache.iotdb.rpc.TSStatusCode;
 
+import java.util.List;
 import java.util.Map;
 
 public class DataNodeInfosResp implements DataSet {
 
   private TSStatus status;
   private Map<Integer, TDataNodeInfo> dataNodeInfoMap;
+  private List<TDataNodesInfo> dataNodesInfoList;
 
   public DataNodeInfosResp() {
     // empty constructor
@@ -47,6 +50,14 @@ public class DataNodeInfosResp implements DataSet {
     this.dataNodeInfoMap = dataNodeInfoMap;
   }
 
+  public List<TDataNodesInfo> getDataNodesInfoList() {
+    return dataNodesInfoList;
+  }
+
+  public void setDataNodesInfoList(List<TDataNodesInfo> dataNodesInfoList) {
+    this.dataNodesInfoList = dataNodesInfoList;
+  }
+
   public void convertToRpcDataNodeLocationResp(TDataNodeInfoResp resp) {
     resp.setStatus(status);
     if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index d87b748455..6ffac63e68 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -20,9 +20,12 @@
 package org.apache.iotdb.confignode.manager;
 
 import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeInfo;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TDataNodesInfo;
 import org.apache.iotdb.common.rpc.thrift.TFlushReq;
+import org.apache.iotdb.common.rpc.thrift.TRegionInfo;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
@@ -84,6 +87,7 @@ import 
org.apache.iotdb.db.mpp.common.schematree.PathPatternTree;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 
+import org.apache.commons.collections4.CollectionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -96,6 +100,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 import static 
org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
@@ -769,6 +774,62 @@ public class ConfigManager implements IManager {
     }
   }
 
+  @Override
+  public DataSet showDataNodes() {
+    TSStatus status = confirmLeader();
+    GetRegionInfoListPlan getRegionsinfoReq = new GetRegionInfoListPlan();
+    DataNodeInfosResp dataNodeInfosResp = new DataNodeInfosResp();
+    if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+      dataNodeInfosResp.setStatus(status);
+      return dataNodeInfosResp;
+    }
+    List<TDataNodesInfo> dataNodesInfoList = 
nodeManager.getOnlineDataNodesInfoList();
+    RegionInfoListResp regionsInfoDataSet =
+        (RegionInfoListResp) 
partitionManager.getRegionInfoList(getRegionsinfoReq);
+
+    // Map<DataNodeId, DataRegionNum>
+    Map<Integer, AtomicInteger> dataRegionNumMap = new HashMap<>();
+    // Map<DataNodeId, SchemaRegionNum>
+    Map<Integer, AtomicInteger> schemaRegionNumMap = new HashMap<>();
+
+    List<TRegionInfo> regionInfoList = regionsInfoDataSet.getRegionInfoList();
+    if (CollectionUtils.isNotEmpty(regionInfoList)) {
+
+      regionInfoList.forEach(
+          (regionInfo) -> {
+            int dataNodeId = regionInfo.getDataNodeId();
+            int regionTypeValue = 
regionInfo.getConsensusGroupId().getType().getValue();
+            int dataRegionNum =
+                regionTypeValue == TConsensusGroupType.DataRegion.getValue() ? 
1 : 0;
+            int schemaRegionNum =
+                regionTypeValue == TConsensusGroupType.SchemaRegion.getValue() 
? 1 : 0;
+            dataRegionNumMap
+                .computeIfAbsent(dataNodeId, key -> new AtomicInteger())
+                .addAndGet(dataRegionNum);
+            schemaRegionNumMap
+                .computeIfAbsent(dataNodeId, key -> new AtomicInteger())
+                .addAndGet(schemaRegionNum);
+          });
+
+      dataNodesInfoList.forEach(
+          (dataNodesInfo -> {
+            if (dataRegionNumMap.containsKey(dataNodesInfo.getDataNodeId())) {
+              dataNodesInfo.setDataRegionNum(
+                  dataRegionNumMap.get(dataNodesInfo.getDataNodeId()).get());
+            }
+            if (schemaRegionNumMap.containsKey(dataNodesInfo.getDataNodeId())) 
{
+              dataNodesInfo.setSchemaRegionNum(
+                  schemaRegionNumMap.get(dataNodesInfo.getDataNodeId()).get());
+            }
+          }));
+    }
+
+    dataNodeInfosResp.setStatus(regionsInfoDataSet.getStatus());
+    dataNodeInfosResp.setDataNodesInfoList(dataNodesInfoList);
+
+    return dataNodeInfosResp;
+  }
+
   public ProcedureManager getProcedureManager() {
     return procedureManager;
   }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java 
b/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
index 10106b3e6f..dd934bad3b 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
@@ -261,4 +261,7 @@ public interface IManager {
 
   /** Show (data/schema) regions */
   DataSet showRegion(GetRegionInfoListPlan getRegionInfoListPlan);
+
+  /** Show datanodes */
+  DataSet showDataNodes();
 }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/manager/NodeManager.java 
b/confignode/src/main/java/org/apache/iotdb/confignode/manager/NodeManager.java
index 0b80adfae8..84dcf4832d 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/manager/NodeManager.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/manager/NodeManager.java
@@ -21,8 +21,10 @@ package org.apache.iotdb.confignode.manager;
 import org.apache.iotdb.common.rpc.thrift.TConfigNodeLocation;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeInfo;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TDataNodesInfo;
 import org.apache.iotdb.common.rpc.thrift.TFlushReq;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.commons.cluster.NodeStatus;
 import org.apache.iotdb.commons.consensus.ConsensusGroupId;
 import org.apache.iotdb.confignode.client.AsyncDataNodeClientPool;
 import org.apache.iotdb.confignode.client.handlers.FlushHandler;
@@ -147,7 +149,6 @@ public class NodeManager {
   public DataNodeInfosResp getDataNodeInfo(GetDataNodeInfoPlan req) {
     return (DataNodeInfosResp) getConsensusManager().read(req).getDataset();
   }
-
   /**
    * Only leader use this interface
    *
@@ -177,6 +178,27 @@ public class NodeManager {
     return nodeInfo.getOnlineDataNodes(dataNodeId);
   }
 
+  public List<TDataNodesInfo> getOnlineDataNodesInfoList() {
+    List<TDataNodesInfo> dataNodesLocations = new ArrayList<>();
+    List<TDataNodeInfo> onlineDataNodes = this.getOnlineDataNodes(-1);
+    if (onlineDataNodes != null) {
+      onlineDataNodes.forEach(
+          (dataNodeInfo) -> {
+            TDataNodesInfo tDataNodesLocation = new TDataNodesInfo();
+            
tDataNodesLocation.setDataNodeId(dataNodeInfo.getLocation().getDataNodeId());
+            tDataNodesLocation.setStatus(NodeStatus.Running.getStatus());
+            tDataNodesLocation.setRpcAddresss(
+                dataNodeInfo.getLocation().getClientRpcEndPoint().getIp());
+            tDataNodesLocation.setRpcPort(
+                dataNodeInfo.getLocation().getClientRpcEndPoint().getPort());
+            tDataNodesLocation.setDataRegionNum(0);
+            tDataNodesLocation.setSchemaRegionNum(0);
+            dataNodesLocations.add(tDataNodesLocation);
+          });
+    }
+    return dataNodesLocations;
+  }
+
   /**
    * Provides ConfigNodeGroup information for the newly registered ConfigNode
    *
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
index 1f738ed078..8406e42a24 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java
@@ -85,6 +85,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TSetDataReplicationFactorReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetSchemaReplicationFactorReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetStorageGroupReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetTimePartitionIntervalReq;
+import org.apache.iotdb.confignode.rpc.thrift.TShowDataNodesResp;
 import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq;
 import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp;
 import org.apache.iotdb.confignode.rpc.thrift.TStorageGroupSchema;
@@ -481,6 +482,15 @@ public class ConfigNodeRPCServiceProcessor implements 
IConfigNodeRPCService.Ifac
     return timestamp;
   }
 
+  @Override
+  public TShowDataNodesResp showDataNodes() throws TException {
+    DataNodeInfosResp dataSet = (DataNodeInfosResp) 
configManager.showDataNodes();
+    TShowDataNodesResp showDataNodesResp = new TShowDataNodesResp();
+    showDataNodesResp.setStatus(dataSet.getStatus());
+    showDataNodesResp.setDataNodesInfoList(dataSet.getDataNodesInfoList());
+    return showDataNodesResp;
+  }
+
   public void handleClientExit() {}
 
   // TODO: Interfaces for data operations
diff --git a/docs/UserGuide/Maintenance-Tools/Maintenance-Command.md 
b/docs/UserGuide/Maintenance-Tools/Maintenance-Command.md
index 25210d8c8b..c4ba3e8e6e 100644
--- a/docs/UserGuide/Maintenance-Tools/Maintenance-Command.md
+++ b/docs/UserGuide/Maintenance-Tools/Maintenance-Command.md
@@ -180,6 +180,61 @@ IoTDB> show schema regions
 Total line number = 2
 It costs 0.012s
 ```
+## Monitoring tool for cluster DataNode distribution
+
+Currently, IoTDB supports DataNode query using the following SQL:
+
+- `SHOW DATANODES`: Show all DataNode
+
+```sql
+IoTDB> create timeseries root.sg.d1.s1 with datatype=BOOLEAN,encoding=PLAIN
+Msg: The statement is executed successfully.
+IoTDB> create timeseries root.sg.d2.s1 with datatype=BOOLEAN,encoding=PLAIN
+Msg: The statement is executed successfully.
+IoTDB> create timeseries root.ln.d1.s1 with datatype=BOOLEAN,encoding=PLAIN
+Msg: The statement is executed successfully.
+IoTDB> show regions
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|RegionId|        Type|Status|storage group|Series Slots|Time 
Slots|DataNodeId|     Host|Port|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|       0|SchemaRegion|    Up|      root.sg|           2|         0|         
1|127.0.0.1|6667|
+|       1|SchemaRegion|    Up|      root.ln|           1|         0|         
2|127.0.0.1|6668|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+Total line number = 2
+It costs 0.013s
+
+IoTDB> show datanodes
++------+-------+---------+----+-------------+---------------+
+|NodeID| Status|     Host|Port|DataRegionNum|SchemaRegionNum|
++------+-------+---------+----+-------------+---------------+
+|     1|Running|127.0.0.1|6667|            0|              1|
+|     2|Running|127.0.0.1|6668|            0|              1|
++------+-------+---------+----+-------------+---------------+
+Total line number = 2
+It costs 0.007s
+
+IoTDB> insert into root.ln.d1(timestamp,s1) values(1,true)
+Msg: The statement is executed successfully.
+IoTDB> show regions
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|RegionId|        Type|Status|storage group|Series Slots|Time 
Slots|DataNodeId|     Host|Port|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|       0|SchemaRegion|    Up|      root.sg|           2|         0|         
1|127.0.0.1|6667|
+|       1|SchemaRegion|    Up|      root.ln|           1|         0|         
2|127.0.0.1|6668|
+|       2|  DataRegion|    Up|      root.ln|           1|         1|         
1|127.0.0.1|6667|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+Total line number = 3
+It costs 0.008s
+IoTDB> show datanodes
++------+-------+---------+----+-------------+---------------+
+|NodeID| Status|     Host|Port|DataRegionNum|SchemaRegionNum|
++------+-------+---------+----+-------------+---------------+
+|     1|Running|127.0.0.1|6667|            1|              1|
+|     2|Running|127.0.0.1|6668|            0|              1|
++------+-------+---------+----+-------------+---------------+
+Total line number = 2
+It costs 0.006s
+```
 
 ## Cluster node status viewing tool 
 
diff --git a/docs/zh/UserGuide/Maintenance-Tools/Maintenance-Command.md 
b/docs/zh/UserGuide/Maintenance-Tools/Maintenance-Command.md
index 212dd04060..cea43734ab 100644
--- a/docs/zh/UserGuide/Maintenance-Tools/Maintenance-Command.md
+++ b/docs/zh/UserGuide/Maintenance-Tools/Maintenance-Command.md
@@ -175,6 +175,61 @@ IoTDB> show schema regions
 Total line number = 2
 It costs 0.012s
 ```
+## 集群 DataNode 分布式监控工具
+
+当前 IoTDB 支持使用如下 SQL 查看 DataNode:
+
+- `SHOW DATANODES`: 展示所有DataNode
+
+```sql
+IoTDB> create timeseries root.sg.d1.s1 with datatype=BOOLEAN,encoding=PLAIN
+Msg: The statement is executed successfully.
+IoTDB> create timeseries root.sg.d2.s1 with datatype=BOOLEAN,encoding=PLAIN
+Msg: The statement is executed successfully.
+IoTDB> create timeseries root.ln.d1.s1 with datatype=BOOLEAN,encoding=PLAIN
+Msg: The statement is executed successfully.
+IoTDB> show regions
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|RegionId|        Type|Status|storage group|Series Slots|Time 
Slots|DataNodeId|     Host|Port|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|       0|SchemaRegion|    Up|      root.sg|           2|         0|         
1|127.0.0.1|6667|
+|       1|SchemaRegion|    Up|      root.ln|           1|         0|         
2|127.0.0.1|6668|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+Total line number = 2
+It costs 0.013s
+
+IoTDB> show datanodes
++------+-------+---------+----+-------------+---------------+
+|NodeID| Status|     Host|Port|DataRegionNum|SchemaRegionNum|
++------+-------+---------+----+-------------+---------------+
+|     1|Running|127.0.0.1|6667|            0|              1|
+|     2|Running|127.0.0.1|6668|            0|              1|
++------+-------+---------+----+-------------+---------------+
+Total line number = 2
+It costs 0.007s
+
+IoTDB> insert into root.ln.d1(timestamp,s1) values(1,true)
+Msg: The statement is executed successfully.
+IoTDB> show regions
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|RegionId|        Type|Status|storage group|Series Slots|Time 
Slots|DataNodeId|     Host|Port|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+|       0|SchemaRegion|    Up|      root.sg|           2|         0|         
1|127.0.0.1|6667|
+|       1|SchemaRegion|    Up|      root.ln|           1|         0|         
2|127.0.0.1|6668|
+|       2|  DataRegion|    Up|      root.ln|           1|         1|         
1|127.0.0.1|6667|
++--------+------------+------+-------------+------------+----------+----------+---------+----+
+Total line number = 3
+It costs 0.008s
+IoTDB> show datanodes
++------+-------+---------+----+-------------+---------------+
+|NodeID| Status|     Host|Port|DataRegionNum|SchemaRegionNum|
++------+-------+---------+----+-------------+---------------+
+|     1|Running|127.0.0.1|6667|            1|              1|
+|     2|Running|127.0.0.1|6668|            0|              1|
++------+-------+---------+----+-------------+---------------+
+Total line number = 2
+It costs 0.006s
+```
 
 ## 集群节点状态查看工具
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java 
b/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java
index 84021bdb1e..4edb3b11b4 100644
--- a/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java
+++ b/server/src/main/java/org/apache/iotdb/db/client/ConfigNodeClient.java
@@ -60,6 +60,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TSetDataReplicationFactorReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetSchemaReplicationFactorReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetStorageGroupReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetTimePartitionIntervalReq;
+import org.apache.iotdb.confignode.rpc.thrift.TShowDataNodesResp;
 import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq;
 import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp;
 import org.apache.iotdb.confignode.rpc.thrift.TStorageGroupSchemaResp;
@@ -680,6 +681,23 @@ public class ConfigNodeClient
     throw new TException(MSG_RECONNECTION_FAIL);
   }
 
+  @Override
+  public TShowDataNodesResp showDataNodes() throws TException {
+    for (int i = 0; i < RETRY_NUM; i++) {
+      try {
+        TShowDataNodesResp showDataNodesResp = client.showDataNodes();
+        showDataNodesResp.setStatus(showDataNodesResp.getStatus());
+        if (!updateConfigNodeLeader(showDataNodesResp.getStatus())) {
+          return showDataNodesResp;
+        }
+      } catch (TException e) {
+        configLeader = null;
+      }
+      reconnect();
+    }
+    throw new TException(MSG_RECONNECTION_FAIL);
+  }
+
   @Override
   public TRegionRouteMapResp getLatestRegionRouteMap() throws TException {
     for (int i = 0; i < RETRY_NUM; i++) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/common/header/HeaderConstant.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/common/header/HeaderConstant.java
index 38a59a61d0..8d3597b918 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/common/header/HeaderConstant.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/common/header/HeaderConstant.java
@@ -76,6 +76,10 @@ public class HeaderConstant {
   public static final String COLUMN_SERIES_SLOTS = "Series Slots";
   public static final String COLUMN_TIME_SLOTS = "Time Slots";
 
+  // column names for show datanodes
+  public static final String COLUMN_DATA_REGION_NUM = "DataRegionNum";
+  public static final String COLUMN_SCHEMA_REGION_NUM = "SchemaRegionNum";
+
   // dataset header for schema statement
   public static final DatasetHeader showTimeSeriesHeader;
   public static final DatasetHeader showDevicesHeader;
@@ -104,6 +108,9 @@ public class HeaderConstant {
   // dataset header for show region
   public static final DatasetHeader showRegionHeader;
 
+  // dataset header for show datanodes
+  public static final DatasetHeader showDataNodesHeader;
+
   static {
     countStorageGroupHeader =
         new DatasetHeader(
@@ -226,4 +233,17 @@ public class HeaderConstant {
                 new ColumnHeader(COLUMN_PORT, TSDataType.INT32)),
             true);
   }
+
+  static {
+    showDataNodesHeader =
+        new DatasetHeader(
+            Arrays.asList(
+                new ColumnHeader(COLUMN_NODE_ID, TSDataType.INT32),
+                new ColumnHeader(COLUMN_STATUS, TSDataType.TEXT),
+                new ColumnHeader(COLUMN_HOST, TSDataType.TEXT),
+                new ColumnHeader(COLUMN_PORT, TSDataType.INT32),
+                new ColumnHeader(COLUMN_DATA_REGION_NUM, TSDataType.INT32),
+                new ColumnHeader(COLUMN_SCHEMA_REGION_NUM, TSDataType.INT32)),
+            true);
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ConfigTaskVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ConfigTaskVisitor.java
index 517b06208f..fd4da7abbc 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ConfigTaskVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ConfigTaskVisitor.java
@@ -29,6 +29,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.DropFunctionStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.SetStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowClusterStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowFunctionsStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowRegionStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStorageGroupStatement;
@@ -129,5 +130,11 @@ public class ConfigTaskVisitor
     return new ShowRegionTask(showRegionStatement);
   }
 
+  @Override
+  public IConfigTask visitShowDataNodes(
+      ShowDataNodesStatement showDataNodesStatement, TaskContext context) {
+    return new ShowDataNodesTask(showDataNodesStatement);
+  }
+
   public static class TaskContext {}
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ShowDataNodesTask.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ShowDataNodesTask.java
new file mode 100644
index 0000000000..b4f3673ce9
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/ShowDataNodesTask.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.mpp.plan.execution.config;
+
+import org.apache.iotdb.common.rpc.thrift.TDataNodesInfo;
+import org.apache.iotdb.confignode.rpc.thrift.TShowDataNodesResp;
+import org.apache.iotdb.db.mpp.common.header.DatasetHeader;
+import org.apache.iotdb.db.mpp.common.header.HeaderConstant;
+import 
org.apache.iotdb.db.mpp.plan.execution.config.executor.IConfigTaskExecutor;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
+import org.apache.iotdb.rpc.TSStatusCode;
+import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
+import org.apache.iotdb.tsfile.utils.Binary;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+public class ShowDataNodesTask implements IConfigTask {
+
+  private ShowDataNodesStatement showDataNodesStatement;
+
+  public ShowDataNodesTask() {}
+
+  public ShowDataNodesTask(ShowDataNodesStatement showDataNodesStatement) {
+    this.showDataNodesStatement = showDataNodesStatement;
+  }
+
+  @Override
+  public ListenableFuture<ConfigTaskResult> execute(IConfigTaskExecutor 
configTaskExecutor)
+      throws InterruptedException {
+    return configTaskExecutor.showDataNodes(showDataNodesStatement);
+  }
+
+  public static void buildTSBlock(
+      TShowDataNodesResp showDataNodesResp, SettableFuture<ConfigTaskResult> 
future) {
+    TsBlockBuilder builder =
+        new 
TsBlockBuilder(HeaderConstant.showDataNodesHeader.getRespDataTypes());
+    if (showDataNodesResp.getDataNodesInfoList() != null) {
+      for (TDataNodesInfo tDataNodesLocation : 
showDataNodesResp.getDataNodesInfoList()) {
+        builder.getTimeColumnBuilder().writeLong(0L);
+        
builder.getColumnBuilder(0).writeInt(tDataNodesLocation.getDataNodeId());
+        builder
+            .getColumnBuilder(1)
+            .writeBinary(
+                Binary.valueOf(
+                    tDataNodesLocation.getStatus() == null ? "" : 
tDataNodesLocation.getStatus()));
+
+        builder
+            .getColumnBuilder(2)
+            .writeBinary(Binary.valueOf(tDataNodesLocation.getRpcAddresss()));
+        builder.getColumnBuilder(3).writeInt(tDataNodesLocation.getRpcPort());
+        
builder.getColumnBuilder(4).writeInt(tDataNodesLocation.getDataRegionNum());
+
+        
builder.getColumnBuilder(5).writeInt(tDataNodesLocation.getSchemaRegionNum());
+        builder.declarePosition();
+      }
+    }
+    DatasetHeader datasetHeader = HeaderConstant.showDataNodesHeader;
+    future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, 
builder.build(), datasetHeader));
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index 37fa9ded56..7f5a0d51ab 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -32,6 +32,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TCreateFunctionReq;
 import org.apache.iotdb.confignode.rpc.thrift.TDeleteStorageGroupsReq;
 import org.apache.iotdb.confignode.rpc.thrift.TDropFunctionReq;
 import org.apache.iotdb.confignode.rpc.thrift.TSetStorageGroupReq;
+import org.apache.iotdb.confignode.rpc.thrift.TShowDataNodesResp;
 import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq;
 import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp;
 import org.apache.iotdb.confignode.rpc.thrift.TStorageGroupSchema;
@@ -43,6 +44,7 @@ import 
org.apache.iotdb.db.mpp.plan.execution.config.ConfigTaskResult;
 import org.apache.iotdb.db.mpp.plan.execution.config.CountStorageGroupTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.SetStorageGroupTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.ShowClusterTask;
+import org.apache.iotdb.db.mpp.plan.execution.config.ShowDataNodesTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.ShowRegionTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.ShowStorageGroupTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.ShowTTLTask;
@@ -50,6 +52,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.CountStorageGroupStatemen
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteStorageGroupStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.SetStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowRegionStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTTLStatement;
@@ -341,4 +344,24 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
     ShowRegionTask.buildTSBlock(showRegionResp, future);
     return future;
   }
+
+  @Override
+  public SettableFuture<ConfigTaskResult> showDataNodes(
+      ShowDataNodesStatement showDataNodesStatement) {
+    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
+    TShowDataNodesResp showDataNodesResp = new TShowDataNodesResp();
+    try (ConfigNodeClient client =
+        
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.partitionRegionId)) {
+      showDataNodesResp = client.showDataNodes();
+      if (showDataNodesResp.getStatus().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+        future.setException(new 
StatementExecutionException(showDataNodesResp.getStatus()));
+        return future;
+      }
+    } catch (TException | IOException e) {
+      future.setException(e);
+    }
+    // build TSBlock
+    ShowDataNodesTask.buildTSBlock(showDataNodesResp, future);
+    return future;
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/IConfigTaskExecutor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/IConfigTaskExecutor.java
index 5d60904d5c..2eadef660c 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/IConfigTaskExecutor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/IConfigTaskExecutor.java
@@ -25,6 +25,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.CountStorageGroupStatemen
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteStorageGroupStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.SetStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowRegionStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTTLStatement;
@@ -61,4 +62,6 @@ public interface IConfigTaskExecutor {
   SettableFuture<ConfigTaskResult> showTTL(ShowTTLStatement showTTLStatement);
 
   SettableFuture<ConfigTaskResult> showRegion(ShowRegionStatement 
showRegionStatement);
+
+  SettableFuture<ConfigTaskResult> showDataNodes(ShowDataNodesStatement 
showDataNodesStatement);
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
index 53da4960f0..c23fef90af 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
@@ -37,6 +37,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.CountStorageGroupStatemen
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteStorageGroupStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.SetStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowRegionStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTTLStatement;
@@ -281,4 +282,16 @@ public class StandaloneConfigTaskExecutor implements 
IConfigTaskExecutor {
                 "Executing show regions in standalone mode is not 
supported")));
     return future;
   }
+
+  @Override
+  public SettableFuture<ConfigTaskResult> showDataNodes(
+      ShowDataNodesStatement showDataNodesStatement) {
+    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
+    future.setException(
+        new StatementExecutionException(
+            RpcUtils.getStatus(
+                TSStatusCode.EXECUTE_STATEMENT_ERROR,
+                "Executing show datanodes in standalone mode is not 
supported")));
+    return future;
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index 4812d928fb..04d50329f9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -96,6 +96,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildPathsStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowClusterStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDevicesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowFunctionsStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowRegionStatement;
@@ -2285,4 +2286,11 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
     }
     return showRegionStatement;
   }
+
+  // show datanodes
+
+  @Override
+  public Statement visitShowDataNodes(IoTDBSqlParser.ShowDataNodesContext ctx) 
{
+    return new ShowDataNodesStatement();
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
index 7f28d05552..02661d1258 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
@@ -48,6 +48,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildPathsStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowClusterStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDataNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDevicesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowFunctionsStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowRegionStatement;
@@ -256,4 +257,8 @@ public abstract class StatementVisitor<R, C> {
   public R visitShowRegion(ShowRegionStatement showRegionStatement, C context) 
{
     return visitStatement(showRegionStatement, context);
   }
+
+  public R visitShowDataNodes(ShowDataNodesStatement showDataNodesStatement, C 
context) {
+    return visitStatement(showDataNodesStatement, context);
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/ShowDataNodesStatement.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/ShowDataNodesStatement.java
new file mode 100644
index 0000000000..0a41ea9192
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/ShowDataNodesStatement.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.mpp.plan.statement.metadata;
+
+import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType;
+import org.apache.iotdb.db.mpp.plan.analyze.QueryType;
+import org.apache.iotdb.db.mpp.plan.statement.IConfigStatement;
+import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
+
+public class ShowDataNodesStatement extends ShowStatement implements 
IConfigStatement {
+
+  public ShowDataNodesStatement() {}
+
+  public ShowDataNodesStatement(TConsensusGroupType regionType) {
+    this.regionType = regionType;
+  }
+
+  private TConsensusGroupType regionType;
+
+  public TConsensusGroupType getRegionType() {
+    return regionType;
+  }
+
+  public void setRegionType(TConsensusGroupType regionType) {
+    this.regionType = regionType;
+  }
+
+  @Override
+  public QueryType getQueryType() {
+    return QueryType.READ;
+  }
+
+  @Override
+  public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
+    return visitor.visitShowDataNodes(this, context);
+  }
+}
diff --git a/thrift-commons/src/main/thrift/common.thrift 
b/thrift-commons/src/main/thrift/common.thrift
index 338927ff72..2a328eefb1 100644
--- a/thrift-commons/src/main/thrift/common.thrift
+++ b/thrift-commons/src/main/thrift/common.thrift
@@ -102,6 +102,15 @@ struct TFlushReq {
    3: optional i32 dataNodeId
 }
 
+struct TDataNodesInfo {
+  1: required i32 dataNodeId
+  2: required string status
+  3: required string rpcAddresss
+  4: required i32 rpcPort
+  5: required i32 dataRegionNum
+  6: required i32 schemaRegionNum
+}
+
 struct TSetTTLReq {
   1: required string storageGroup
   2: required i64 TTL
diff --git a/thrift-confignode/src/main/thrift/confignode.thrift 
b/thrift-confignode/src/main/thrift/confignode.thrift
index 75059ddf08..9aed98654d 100644
--- a/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/thrift-confignode/src/main/thrift/confignode.thrift
@@ -235,6 +235,12 @@ struct TShowRegionResp {
   2: optional list<common.TRegionInfo> regionInfoList;
 }
 
+// show datanodes
+struct TShowDataNodesResp {
+  1: required common.TSStatus status
+  2: optional list<common.TDataNodesInfo> dataNodesInfoList
+}
+
 struct TRegionRouteMapResp {
   1: required common.TSStatus status
   // For version stamp
@@ -337,5 +343,9 @@ service IConfigNodeRPCService {
 
   i64 getConfigNodeHeartBeat(i64 timestamp)
 
+  /* Show DataNodes */
+
+  TShowDataNodesResp showDataNodes()
+
 }
 

Reply via email to