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 d6bc676876 [IOTDB-4061] Support hot configuration of data_dirs (#7021)
d6bc676876 is described below

commit d6bc676876d5191ba089f8645457769de5337615
Author: Alan Choo <[email protected]>
AuthorDate: Wed Aug 17 14:48:05 2022 +0800

    [IOTDB-4061] Support hot configuration of data_dirs (#7021)
---
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |  2 +-
 .../confignode/client/DataNodeRequestType.java     |  3 +-
 .../async/datanode/AsyncDataNodeClientPool.java    | 13 ++++
 .../async/handlers/LoadConfigurationHandler.java   | 82 ++++++++++++++++++++++
 .../iotdb/confignode/manager/ConfigManager.java    |  8 +++
 .../apache/iotdb/confignode/manager/IManager.java  |  3 +
 .../iotdb/confignode/manager/NodeManager.java      | 14 ++++
 .../thrift/ConfigNodeRPCServiceProcessor.java      |  5 ++
 .../apache/iotdb/db/client/ConfigNodeClient.java   | 16 +++++
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 14 +++-
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  3 +-
 .../db/conf/directories/DirectoryManager.java      |  9 +++
 .../iotdb/db/localconfignode/LocalConfigNode.java  | 10 +++
 .../iotdb/db/mpp/plan/constant/StatementType.java  |  2 +-
 .../plan/execution/config/ConfigTaskVisitor.java   |  8 +++
 .../config/executor/ClusterConfigTaskExecutor.java | 24 +++++++
 .../config/executor/IConfigTaskExecutor.java       |  2 +
 .../executor/StandaloneConfigTaskExecutor.java     | 13 ++++
 .../config/sys/LoadConfigurationTask.java          | 42 +++++++++++
 .../iotdb/db/mpp/plan/parser/ASTVisitor.java       | 19 +++++
 .../db/mpp/plan/statement/StatementVisitor.java    |  6 ++
 .../statement/sys/LoadConfigurationStatement.java  | 60 ++++++++++++++++
 .../db/service/metrics/predefined/FileMetrics.java |  4 +-
 .../impl/DataNodeInternalRPCServiceImpl.java       | 12 ++++
 .../src/main/thrift/confignode.thrift              |  3 +
 thrift/src/main/thrift/datanode.thrift             |  2 +
 26 files changed, 372 insertions(+), 7 deletions(-)

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 3cf6157c0f..18c4115d9c 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
@@ -688,7 +688,7 @@ revokeWatermarkEmbedding
 
 // Load Configuration
 loadConfiguration
-    : LOAD CONFIGURATION (MINUS GLOBAL)?
+    : LOAD CONFIGURATION (MINUS GLOBAL)? (ON (LOCAL | CLUSTER))?
     ;
 
 // Load Timeseries
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java
index 7fc041f37e..04c8347395 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/client/DataNodeRequestType.java
@@ -42,5 +42,6 @@ public enum DataNodeRequestType {
   UPDATE_TEMPLATE,
   CLEAR_CACHE,
   MERGE,
-  FULL_MERGE
+  FULL_MERGE,
+  LOAD_CONFIGURATION,
 }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/client/async/datanode/AsyncDataNodeClientPool.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/client/async/datanode/AsyncDataNodeClientPool.java
index 63f0778f72..08bca91b6f 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/client/async/datanode/AsyncDataNodeClientPool.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/client/async/datanode/AsyncDataNodeClientPool.java
@@ -34,6 +34,7 @@ import 
org.apache.iotdb.confignode.client.async.handlers.ClearCacheHandler;
 import org.apache.iotdb.confignode.client.async.handlers.CreateRegionHandler;
 import org.apache.iotdb.confignode.client.async.handlers.FlushHandler;
 import 
org.apache.iotdb.confignode.client.async.handlers.FunctionManagementHandler;
+import 
org.apache.iotdb.confignode.client.async.handlers.LoadConfigurationHandler;
 import org.apache.iotdb.confignode.client.async.handlers.MergeHandler;
 import org.apache.iotdb.confignode.client.async.handlers.SetTTLHandler;
 import 
org.apache.iotdb.confignode.client.async.handlers.UpdateConfigNodeGroupHandler;
@@ -134,6 +135,15 @@ public class AsyncDataNodeClientPool {
                     dataNodeLocationMap,
                     dataNodeResponseStatus);
             break;
+          case LOAD_CONFIGURATION:
+            handler =
+                new LoadConfigurationHandler(
+                    countDownLatch,
+                    requestType,
+                    targetDataNode,
+                    dataNodeLocationMap,
+                    dataNodeResponseStatus);
+            break;
           case UPDATE_REGION_ROUTE_MAP:
             handler =
                 new UpdateRegionRouteMapHandler(
@@ -195,6 +205,9 @@ public class AsyncDataNodeClientPool {
         case CLEAR_CACHE:
           client.clearCache((ClearCacheHandler) handler);
           break;
+        case LOAD_CONFIGURATION:
+          client.loadConfiguration((LoadConfigurationHandler) handler);
+          break;
         case UPDATE_REGION_ROUTE_MAP:
           client.updateRegionCache((TRegionRouteReq) req, 
(UpdateRegionRouteMapHandler) handler);
           break;
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/LoadConfigurationHandler.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/LoadConfigurationHandler.java
new file mode 100644
index 0000000000..198ce3f5f6
--- /dev/null
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/LoadConfigurationHandler.java
@@ -0,0 +1,82 @@
+/*
+ * 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.confignode.client.async.handlers;
+
+import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.confignode.client.DataNodeRequestType;
+import org.apache.iotdb.rpc.RpcUtils;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+public class LoadConfigurationHandler extends AbstractRetryHandler
+    implements AsyncMethodCallback<TSStatus> {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(LoadConfigurationHandler.class);
+
+  private final List<TSStatus> dataNodeResponseStatus;
+
+  public LoadConfigurationHandler(
+      CountDownLatch countDownLatch,
+      DataNodeRequestType requestType,
+      TDataNodeLocation targetDataNode,
+      Map<Integer, TDataNodeLocation> dataNodeLocationMap,
+      List<TSStatus> dataNodeResponseStatus) {
+    super(countDownLatch, requestType, targetDataNode, dataNodeLocationMap);
+    this.dataNodeResponseStatus = dataNodeResponseStatus;
+  }
+
+  @Override
+  public void onComplete(TSStatus response) {
+    if (response.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+      dataNodeResponseStatus.add(response);
+      dataNodeLocationMap.remove(targetDataNode.getDataNodeId());
+      LOGGER.info("Successfully Load Configuration on DataNode: {}", 
targetDataNode);
+    } else {
+      dataNodeResponseStatus.add(response);
+      LOGGER.error(
+          "Failed to Load Configuration on DataNode {}, {}",
+          dataNodeLocationMap.get(targetDataNode.getDataNodeId()),
+          response);
+    }
+    countDownLatch.countDown();
+  }
+
+  @Override
+  public void onError(Exception exception) {
+    countDownLatch.countDown();
+    dataNodeResponseStatus.add(
+        new TSStatus(
+            RpcUtils.getStatus(
+                TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode(),
+                "Load Configuration error on DataNode: {id="
+                    + targetDataNode.getDataNodeId()
+                    + ", internalEndPoint="
+                    + targetDataNode.getInternalEndPoint()
+                    + "}"
+                    + exception.getMessage())));
+  }
+}
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 b5b93d5267..8a825ca760 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
@@ -830,6 +830,14 @@ public class ConfigManager implements IManager {
         : status;
   }
 
+  @Override
+  public TSStatus loadConfiguration() {
+    TSStatus status = confirmLeader();
+    return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()
+        ? RpcUtils.squashResponseStatusList(nodeManager.loadConfiguration())
+        : status;
+  }
+
   @Override
   public TRegionRouteMapResp getLatestRegionRouteMap() {
     TSStatus status = confirmLeader();
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 8412372bb4..08d822d3c6 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
@@ -285,6 +285,9 @@ public interface IManager {
   /** Clear cache on all DataNodes */
   TSStatus clearCache();
 
+  /** Load configuration on all DataNodes */
+  TSStatus loadConfiguration();
+
   /**
    * Get the latest RegionRouteMap
    *
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 f188ae7148..d602b0d5dc 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
@@ -399,6 +399,20 @@ public class NodeManager {
     return dataNodeResponseStatus;
   }
 
+  public List<TSStatus> loadConfiguration() {
+    Map<Integer, TDataNodeLocation> dataNodeLocationMap =
+        configManager.getNodeManager().getRegisteredDataNodeLocations();
+    List<TSStatus> dataNodeResponseStatus =
+        Collections.synchronizedList(new 
ArrayList<>(dataNodeLocationMap.size()));
+    AsyncDataNodeClientPool.getInstance()
+        .sendAsyncRequestToDataNodeWithRetry(
+            null,
+            dataNodeLocationMap,
+            DataNodeRequestType.LOAD_CONFIGURATION,
+            dataNodeResponseStatus);
+    return dataNodeResponseStatus;
+  }
+
   /** Start the heartbeat service */
   public void startHeartbeatService() {
     synchronized (scheduleMonitor) {
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 014f333491..90dfdc2c11 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
@@ -529,6 +529,11 @@ public class ConfigNodeRPCServiceProcessor implements 
IConfigNodeRPCService.Ifac
     return configManager.clearCache();
   }
 
+  @Override
+  public TSStatus loadConfiguration() {
+    return configManager.loadConfiguration();
+  }
+
   @Override
   public TShowRegionResp showRegion(TShowRegionReq showRegionReq) throws 
TException {
     GetRegionInfoListPlan getRegionInfoListPlan = new 
GetRegionInfoListPlan(showRegionReq);
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 f181ce7249..4e43299f91 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
@@ -796,6 +796,22 @@ public class ConfigNodeClient
     throw new TException(MSG_RECONNECTION_FAIL);
   }
 
+  @Override
+  public TSStatus loadConfiguration() throws TException {
+    for (int i = 0; i < RETRY_NUM; i++) {
+      try {
+        TSStatus status = client.loadConfiguration();
+        if (!updateConfigNodeLeader(status)) {
+          return status;
+        }
+      } catch (TException e) {
+        configLeader = null;
+      }
+      reconnect();
+    }
+    throw new TException(MSG_RECONNECTION_FAIL);
+  }
+
   @Override
   public TShowRegionResp showRegion(TShowRegionReq req) throws TException {
     for (int i = 0; i < RETRY_NUM; i++) {
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java 
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index ddedb1b676..2aa2b771ac 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -50,6 +50,7 @@ import java.io.File;
 import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
@@ -1087,6 +1088,7 @@ public class IoTDBConfig {
   }
 
   void reloadDataDirs(String[] dataDirs) throws LoadConfigurationException {
+    // format data directories
     if 
(TSFileDescriptor.getInstance().getConfig().getTSFileStorageFs().equals(FSType.HDFS))
 {
       String hdfsDir = getHdfsDir();
       for (int i = 0; i < dataDirs.length; i++) {
@@ -1097,6 +1099,16 @@ public class IoTDBConfig {
         dataDirs[i] = addHomeDir(dataDirs[i]);
       }
     }
+    // make sure old data directories not removed
+    HashSet<String> newDirs = new HashSet<>(Arrays.asList(dataDirs));
+    for (String oldDir : this.dataDirs) {
+      if (!newDirs.contains(oldDir)) {
+        String msg =
+            String.format("%s is removed from data_dirs parameter, please add 
it back.", oldDir);
+        logger.error(msg);
+        throw new LoadConfigurationException(msg);
+      }
+    }
     this.dataDirs = dataDirs;
     DirectoryManager.getInstance().updateFileFolders();
   }
@@ -1113,7 +1125,7 @@ public class IoTDBConfig {
     return dir;
   }
 
-  private void confirmMultiDirStrategy() {
+  void confirmMultiDirStrategy() {
     if (getMultiDirStrategyClassName() == null) {
       multiDirStrategyClassName = DEFAULT_MULTI_DIR_STRATEGY;
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java 
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index 80f906470f..dec138deb1 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -1338,11 +1338,12 @@ public class IoTDBDescriptor {
         conf.reloadDataDirs(dataDirs.split(","));
       }
 
-      // update dir strategy
+      // update dir strategy, must update after data dirs
       String multiDirStrategyClassName = 
properties.getProperty("multi_dir_strategy", null);
       if (multiDirStrategyClassName != null
           && 
!multiDirStrategyClassName.equals(conf.getMultiDirStrategyClassName())) {
         conf.setMultiDirStrategyClassName(multiDirStrategyClassName);
+        conf.confirmMultiDirStrategy();
         DirectoryManager.getInstance().updateDirectoryStrategy();
       }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/conf/directories/DirectoryManager.java
 
b/server/src/main/java/org/apache/iotdb/db/conf/directories/DirectoryManager.java
index d9f50444bf..7b3a1478b9 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/conf/directories/DirectoryManager.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/conf/directories/DirectoryManager.java
@@ -80,10 +80,19 @@ public class DirectoryManager {
     try {
       List<String> sequenceFileFolders =
           new 
ArrayList<>(Arrays.asList(IoTDBDescriptor.getInstance().getConfig().getDataDirs()));
+      for (int i = 0; i < sequenceFileFolders.size(); i++) {
+        sequenceFileFolders.set(
+            i, sequenceFileFolders.get(i) + File.separator + 
IoTDBConstant.SEQUENCE_FLODER_NAME);
+      }
       mkDataDirs(sequenceFileFolders);
 
       List<String> unsequenceFileFolders =
           new 
ArrayList<>(Arrays.asList(IoTDBDescriptor.getInstance().getConfig().getDataDirs()));
+      for (int i = 0; i < unsequenceFileFolders.size(); i++) {
+        unsequenceFileFolders.set(
+            i,
+            unsequenceFileFolders.get(i) + File.separator + 
IoTDBConstant.UNSEQUENCE_FLODER_NAME);
+      }
       mkDataDirs(unsequenceFileFolders);
       sequenceStrategy.setFolders(sequenceFileFolders);
       unsequenceStrategy.setFolders(unsequenceFileFolders);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java 
b/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
index ec3aaf1195..0a00f75665 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
@@ -61,6 +61,7 @@ import 
org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import 
org.apache.iotdb.db.exception.metadata.template.UndefinedTemplateException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
 import org.apache.iotdb.db.metadata.LocalSchemaProcessor;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
@@ -1314,4 +1315,13 @@ public class LocalConfigNode {
     BloomFilterCache.getInstance().clear();
     return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
   }
+
+  public TSStatus executeLoadConfigurationOperation() {
+    try {
+      IoTDBDescriptor.getInstance().loadHotModifiedProps();
+    } catch (QueryProcessException e) {
+      return RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, 
e.getMessage());
+    }
+    return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
index 5846f70bc6..17b3874065 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/constant/StatementType.java
@@ -139,5 +139,5 @@ public enum StatementType {
   FETCH_SCHEMA,
   INTERNAL_CREATE_TIMESERIES,
 
-  COUNT
+  COUNT,
 }
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 0ef41c3612..32789490ce 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
@@ -41,6 +41,7 @@ import 
org.apache.iotdb.db.mpp.plan.execution.config.metadata.template.ShowSchem
 import org.apache.iotdb.db.mpp.plan.execution.config.sys.AuthorizerTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.sys.ClearCacheTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.sys.FlushTask;
+import org.apache.iotdb.db.mpp.plan.execution.config.sys.LoadConfigurationTask;
 import org.apache.iotdb.db.mpp.plan.execution.config.sys.MergeTask;
 import org.apache.iotdb.db.mpp.plan.statement.Statement;
 import org.apache.iotdb.db.mpp.plan.statement.StatementNode;
@@ -67,6 +68,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowSchemaTempla
 import org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ClearCacheStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.FlushStatement;
+import org.apache.iotdb.db.mpp.plan.statement.sys.LoadConfigurationStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.MergeStatement;
 import org.apache.iotdb.tsfile.exception.NotImplementedException;
 
@@ -154,6 +156,12 @@ public class ConfigTaskVisitor
     return new ClearCacheTask(clearCacheStatement);
   }
 
+  @Override
+  public IConfigTask visitLoadConfiguration(
+      LoadConfigurationStatement loadConfigurationStatement, TaskContext 
context) {
+    return new LoadConfigurationTask(loadConfigurationStatement);
+  }
+
   @Override
   public IConfigTask visitDropFunction(
       DropFunctionStatement dropFunctionStatement, TaskContext context) {
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 9ad3d6a84d..f50fb5ec11 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
@@ -70,6 +70,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.SetSchemaTemplat
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowNodesInSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowPathSetTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowSchemaTemplateStatement;
+import org.apache.iotdb.rpc.StatementExecutionException;
 import org.apache.iotdb.rpc.TSStatusCode;
 
 import com.google.common.util.concurrent.SettableFuture;
@@ -336,6 +337,29 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
     return future;
   }
 
+  @Override
+  public SettableFuture<ConfigTaskResult> loadConfiguration(boolean isCluster) 
{
+    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
+    TSStatus tsStatus = new TSStatus();
+    if (isCluster) {
+      try (ConfigNodeClient client =
+          
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.partitionRegionId)) {
+        // Send request to some API server
+        tsStatus = client.loadConfiguration();
+      } catch (IOException | TException e) {
+        future.setException(e);
+      }
+    } else {
+      tsStatus = 
LocalConfigNode.getInstance().executeLoadConfigurationOperation();
+    }
+    if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+      future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
+    } else {
+      future.setException(new StatementExecutionException(tsStatus));
+    }
+    return future;
+  }
+
   @Override
   public SettableFuture<ConfigTaskResult> showCluster() {
     SettableFuture<ConfigTaskResult> future = SettableFuture.create();
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 c7a80f6f21..18cd8fd973 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
@@ -66,6 +66,8 @@ public interface IConfigTaskExecutor {
 
   SettableFuture<ConfigTaskResult> clearCache(boolean isCluster);
 
+  SettableFuture<ConfigTaskResult> loadConfiguration(boolean isCluster);
+
   SettableFuture<ConfigTaskResult> showCluster();
 
   SettableFuture<ConfigTaskResult> showTTL(ShowTTLStatement showTTLStatement);
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 d242933842..25ebce7694 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
@@ -46,6 +46,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.SetSchemaTemplat
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowNodesInSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowPathSetTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowSchemaTemplateStatement;
+import org.apache.iotdb.rpc.StatementExecutionException;
 import org.apache.iotdb.rpc.TSStatusCode;
 
 import com.google.common.util.concurrent.SettableFuture;
@@ -252,6 +253,18 @@ public class StandaloneConfigTaskExecutor implements 
IConfigTaskExecutor {
     return future;
   }
 
+  @Override
+  public SettableFuture<ConfigTaskResult> loadConfiguration(boolean isCluster) 
{
+    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
+    TSStatus tsStatus = 
LocalConfigNode.getInstance().executeLoadConfigurationOperation();
+    if (tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+      future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
+    } else {
+      future.setException(new StatementExecutionException(tsStatus));
+    }
+    return future;
+  }
+
   @Override
   public SettableFuture<ConfigTaskResult> showCluster() {
     SettableFuture<ConfigTaskResult> future = SettableFuture.create();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/sys/LoadConfigurationTask.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/sys/LoadConfigurationTask.java
new file mode 100644
index 0000000000..97c8b4d618
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/sys/LoadConfigurationTask.java
@@ -0,0 +1,42 @@
+/*
+ * 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.sys;
+
+import org.apache.iotdb.db.mpp.plan.execution.config.ConfigTaskResult;
+import org.apache.iotdb.db.mpp.plan.execution.config.IConfigTask;
+import 
org.apache.iotdb.db.mpp.plan.execution.config.executor.IConfigTaskExecutor;
+import org.apache.iotdb.db.mpp.plan.statement.sys.LoadConfigurationStatement;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class LoadConfigurationTask implements IConfigTask {
+  private LoadConfigurationStatement loadConfigurationStatement;
+
+  public LoadConfigurationTask(LoadConfigurationStatement 
loadConfigurationStatement) {
+    this.loadConfigurationStatement = loadConfigurationStatement;
+  }
+
+  @Override
+  public ListenableFuture<ConfigTaskResult> execute(IConfigTaskExecutor 
configTaskExecutor)
+      throws InterruptedException {
+    // If the action is executed successfully, return the Future.
+    // If your operation is async, you can return the corresponding future 
directly.
+    return 
configTaskExecutor.loadConfiguration(loadConfigurationStatement.isCluster());
+  }
+}
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 1e444deaa3..d306127944 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
@@ -119,6 +119,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ClearCacheStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ExplainStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.FlushStatement;
+import org.apache.iotdb.db.mpp.plan.statement.sys.LoadConfigurationStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.MergeStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ShowVersionStatement;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
@@ -2380,6 +2381,24 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
     return clearCacheStatement;
   }
 
+  // Load Configuration
+
+  @Override
+  public Statement 
visitLoadConfiguration(IoTDBSqlParser.LoadConfigurationContext ctx) {
+    LoadConfigurationStatement loadConfigurationStatement =
+        new LoadConfigurationStatement(StatementType.LOAD_CONFIGURATION);
+    if (ctx.CLUSTER() != null && 
!IoTDBDescriptor.getInstance().getConfig().isClusterMode()) {
+      throw new SemanticException(
+          "LOAD CONFIGURATION ON CLUSTER is not supported in standalone mode");
+    }
+    if (ctx.LOCAL() != null) {
+      loadConfigurationStatement.setCluster(false);
+    } else {
+      loadConfigurationStatement.setCluster(true);
+    }
+    return loadConfigurationStatement;
+  }
+
   // show region
 
   @Override
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 ca040dc46e..25a6494987 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
@@ -67,6 +67,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ClearCacheStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ExplainStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.FlushStatement;
+import org.apache.iotdb.db.mpp.plan.statement.sys.LoadConfigurationStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.MergeStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ShowVersionStatement;
 
@@ -267,6 +268,11 @@ public abstract class StatementVisitor<R, C> {
     return visitStatement(clearCacheStatement, context);
   }
 
+  public R visitLoadConfiguration(
+      LoadConfigurationStatement loadConfigurationStatement, C context) {
+    return visitStatement(loadConfigurationStatement, context);
+  }
+
   public R visitShowRegion(ShowRegionStatement showRegionStatement, C context) 
{
     return visitStatement(showRegionStatement, context);
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/LoadConfigurationStatement.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/LoadConfigurationStatement.java
new file mode 100644
index 0000000000..ce6cf13d6a
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/sys/LoadConfigurationStatement.java
@@ -0,0 +1,60 @@
+/*
+ * 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.sys;
+
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.mpp.plan.analyze.QueryType;
+import org.apache.iotdb.db.mpp.plan.constant.StatementType;
+import org.apache.iotdb.db.mpp.plan.statement.IConfigStatement;
+import org.apache.iotdb.db.mpp.plan.statement.Statement;
+import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
+
+import java.util.Collections;
+import java.util.List;
+
+public class LoadConfigurationStatement extends Statement implements 
IConfigStatement {
+  private boolean isCluster;
+
+  public LoadConfigurationStatement(StatementType loadConfigurationType) {
+    this.statementType = loadConfigurationType;
+  }
+
+  public boolean isCluster() {
+    return isCluster;
+  }
+
+  public void setCluster(boolean isCluster) {
+    this.isCluster = isCluster;
+  }
+
+  @Override
+  public QueryType getQueryType() {
+    return QueryType.WRITE;
+  }
+
+  @Override
+  public List<PartialPath> getPaths() {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
+    return visitor.visitLoadConfiguration(this, context);
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
 
b/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
index c2573ac5a8..0c490ce4e2 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
@@ -39,8 +39,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
 
 public class FileMetrics implements IMetricSet {
-  private final String[] walDirs = 
IoTDBDescriptor.getInstance().getConfig().getWalDirs();
-  private final String[] dataDirs = 
IoTDBDescriptor.getInstance().getConfig().getDataDirs();
   private final ScheduledExecutorService service = 
Executors.newSingleThreadScheduledExecutor();
   private long walFileTotalSize = 0L;
   private long walFileTotalCount = 0L;
@@ -116,6 +114,8 @@ public class FileMetrics implements IMetricSet {
   }
 
   private void collect() {
+    String[] dataDirs = 
IoTDBDescriptor.getInstance().getConfig().getDataDirs();
+    String[] walDirs = IoTDBDescriptor.getInstance().getConfig().getWalDirs();
     walFileTotalSize = WALManager.getInstance().getTotalDiskUsage();
     sequenceFileTotalSize =
         Stream.of(dataDirs)
diff --git 
a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
 
b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
index d44d9318a8..1042cb81ab 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
@@ -43,6 +43,7 @@ import 
org.apache.iotdb.consensus.common.response.ConsensusWriteResponse;
 import org.apache.iotdb.consensus.exception.PeerNotInConsensusGroupException;
 import org.apache.iotdb.db.auth.AuthorizerManager;
 import org.apache.iotdb.db.client.ConfigNodeInfo;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.consensus.DataRegionConsensusImpl;
 import org.apache.iotdb.db.consensus.SchemaRegionConsensusImpl;
 import org.apache.iotdb.db.engine.StorageEngineV2;
@@ -51,6 +52,7 @@ import org.apache.iotdb.db.engine.cache.ChunkCache;
 import org.apache.iotdb.db.engine.cache.TimeSeriesMetadataCache;
 import org.apache.iotdb.db.exception.DataRegionException;
 import org.apache.iotdb.db.exception.StorageEngineException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.metadata.cache.DataNodeSchemaCache;
 import org.apache.iotdb.db.metadata.schemaregion.SchemaEngine;
@@ -503,6 +505,16 @@ public class DataNodeInternalRPCServiceImpl implements 
IDataNodeRPCService.Iface
     return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
   }
 
+  @Override
+  public TSStatus loadConfiguration() throws TException {
+    try {
+      IoTDBDescriptor.getInstance().loadHotModifiedProps();
+    } catch (QueryProcessException e) {
+      return RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, 
e.getMessage());
+    }
+    return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+  }
+
   @Override
   public TSStatus setTTL(TSetTTLReq req) throws TException {
     return storageEngine.setTTL(req);
diff --git a/thrift-confignode/src/main/thrift/confignode.thrift 
b/thrift-confignode/src/main/thrift/confignode.thrift
index 5824eaf8ce..2421aefa71 100644
--- a/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/thrift-confignode/src/main/thrift/confignode.thrift
@@ -605,6 +605,9 @@ service IConfigNodeRPCService {
   /** Clear the cache of chunk, chunk metadata and timeseries metadata to 
release the memory footprint on all DataNodes */
   common.TSStatus clearCache()
 
+  /** Load configuration on all DataNodes */
+  common.TSStatus loadConfiguration()
+
   // ======================================================
   // Cluster Tools
   // ======================================================
diff --git a/thrift/src/main/thrift/datanode.thrift 
b/thrift/src/main/thrift/datanode.thrift
index a4544fd50a..3f74fdac49 100644
--- a/thrift/src/main/thrift/datanode.thrift
+++ b/thrift/src/main/thrift/datanode.thrift
@@ -351,6 +351,8 @@ service IDataNodeRPCService {
 
   common.TSStatus clearCache()
 
+  common.TSStatus loadConfiguration()
+
   /**
    * Config node will Set the TTL for the storage group on a list of data 
nodes.
    */

Reply via email to