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

jt2594838 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 cb6a309521d Fix Region recovery validation before DataNode startup 
success (#18311)
cb6a309521d is described below

commit cb6a309521dc274dfa79dd1a5720851dac2670ad
Author: Caideyipi <[email protected]>
AuthorDate: Mon Jul 27 18:13:02 2026 +0800

    Fix Region recovery validation before DataNode startup success (#18311)
    
    * Fix NPE when creating SchemaRegion state machine
    
    * Propagate Region recovery failures before startup success
---
 .../consensus/i18n/IoTConsensusV2Messages.java     |  3 -
 .../consensus/i18n/IoTConsensusV2Messages.java     |  3 -
 .../iotdb/consensus/pipe/IoTConsensusV2.java       | 88 +++++++++++++---------
 .../iotdb/consensus/pipe/IoTConsensusV2Test.java   | 55 ++++++++++++++
 .../apache/iotdb/db/i18n/DataNodeMiscMessages.java |  5 +-
 .../iotdb/db/i18n/DataNodeSchemaMessages.java      |  1 +
 .../iotdb/db/i18n/StorageEngineMessages.java       | 11 ++-
 .../apache/iotdb/db/i18n/DataNodeMiscMessages.java |  5 +-
 .../iotdb/db/i18n/DataNodeSchemaMessages.java      |  1 +
 .../iotdb/db/i18n/StorageEngineMessages.java       | 11 ++-
 .../db/consensus/SchemaRegionConsensusImpl.java    | 25 +++++-
 .../java/org/apache/iotdb/db/service/DataNode.java | 13 ++--
 .../iotdb/db/storageengine/StorageEngine.java      |  6 +-
 .../db/storageengine/dataregion/DataRegion.java    |  5 --
 14 files changed, 158 insertions(+), 74 deletions(-)

diff --git 
a/iotdb-core/consensus/src/main/i18n/en/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
 
b/iotdb-core/consensus/src/main/i18n/en/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
index 2bf2a80e94a..03e69119f5d 100644
--- 
a/iotdb-core/consensus/src/main/i18n/en/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
+++ 
b/iotdb-core/consensus/src/main/i18n/en/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
@@ -39,9 +39,6 @@ public final class IoTConsensusV2Messages {
       "Failed to recover consensus from {} for {}, ignore it and continue 
recover other group, async backend checker thread will automatically deregister 
related pipe side effects for this failed consensus group.";
   public static final String FAILED_RECOVER_CONSENSUS_READ_DIR =
       "Failed to recover consensus from {} because read dir failed";
-  public static final String FAILED_RECOVER_CONSENSUS_SHORT =
-      "Failed to recover consensus from {}";
-
   // ===================== IoTConsensusV2 peer operations =====================
 
   public static final String START_DELETE_LOCAL_PEER =
diff --git 
a/iotdb-core/consensus/src/main/i18n/zh/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
 
b/iotdb-core/consensus/src/main/i18n/zh/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
index c3d705f861b..e5a6e55cb79 100644
--- 
a/iotdb-core/consensus/src/main/i18n/zh/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
+++ 
b/iotdb-core/consensus/src/main/i18n/zh/org/apache/iotdb/consensus/i18n/IoTConsensusV2Messages.java
@@ -38,9 +38,6 @@ public final class IoTConsensusV2Messages {
       "从 {} 恢复共识组 {} 失败,忽略并继续恢复其他组,异步后台检查线程将自动注销该失败共识组的 pipe 副作用。";
   public static final String FAILED_RECOVER_CONSENSUS_READ_DIR =
       "从 {} 恢复共识失败,因为读取目录失败";
-  public static final String FAILED_RECOVER_CONSENSUS_SHORT =
-      "从 {} 恢复共识失败";
-
   // ===================== IoTConsensusV2 peer 操作 =====================
 
   public static final String START_DELETE_LOCAL_PEER =
diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2.java
index cf1d4056398..4a207331564 100644
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2.java
+++ 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2.java
@@ -73,6 +73,7 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -125,15 +126,32 @@ public class IoTConsensusV2 implements IConsensus {
       throw new IOException(e);
     }
 
+    waitForRecovery(recoverFuture);
+  }
+
+  static void waitForRecovery(Future<Void> recoverFuture) throws IOException {
     try {
       recoverFuture.get();
-    } catch (CancellationException ce) {
-      LOGGER.info(IoTConsensusV2Messages.RECOVER_TASK_CANCELLED, ce);
-    } catch (ExecutionException ee) {
-      LOGGER.error(IoTConsensusV2Messages.RECOVER_FUTURE_EXCEPTION, ee);
-    } catch (InterruptedException ie) {
+    } catch (CancellationException e) {
+      throw new IOException(IoTConsensusV2Messages.RECOVER_TASK_CANCELLED, e);
+    } catch (ExecutionException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof CompletionException && cause.getCause() != null) {
+        cause = cause.getCause();
+      }
+      if (cause instanceof IOException) {
+        throw (IOException) cause;
+      }
+      if (cause instanceof RuntimeException) {
+        throw (RuntimeException) cause;
+      }
+      if (cause instanceof Error) {
+        throw (Error) cause;
+      }
+      throw new IOException(IoTConsensusV2Messages.RECOVER_FUTURE_EXCEPTION, 
cause);
+    } catch (InterruptedException e) {
       Thread.currentThread().interrupt();
-      LOGGER.warn(IoTConsensusV2Messages.RECOVER_TASK_INTERRUPTED, ie);
+      throw new IOException(IoTConsensusV2Messages.RECOVER_TASK_INTERRUPTED, 
e);
     }
   }
 
@@ -149,39 +167,35 @@ public class IoTConsensusV2 implements IConsensus {
     } else {
       // asynchronously recover, retry logic is implemented at 
IoTConsensusV2Impl
       return CompletableFuture.runAsync(
-              () -> {
-                try (DirectoryStream<Path> stream = 
Files.newDirectoryStream(storageDir.toPath())) {
-                  for (Path path : stream) {
-                    ConsensusGroupId consensusGroupId =
-                        parsePeerFileName(path.getFileName().toString());
-                    try {
-                      IoTConsensusV2ServerImpl consensus =
-                          new IoTConsensusV2ServerImpl(
-                              new Peer(consensusGroupId, thisNodeId, thisNode),
-                              registry.apply(consensusGroupId),
-                              new ArrayList<>(),
-                              config,
-                              syncClientManager);
-                      stateMachineMap.put(consensusGroupId, consensus);
-                      checkPeerListAndStartIfEligible(consensusGroupId, 
consensus);
-                    } catch (Exception e) {
-                      LOGGER.error(
-                          IoTConsensusV2Messages.FAILED_RECOVER_CONSENSUS,
-                          storageDir,
-                          consensusGroupId,
-                          e);
-                    }
-                  }
-                } catch (IOException e) {
+          () -> {
+            try (DirectoryStream<Path> stream = 
Files.newDirectoryStream(storageDir.toPath())) {
+              for (Path path : stream) {
+                ConsensusGroupId consensusGroupId =
+                    parsePeerFileName(path.getFileName().toString());
+                IStateMachine stateMachine = registry.apply(consensusGroupId);
+                try {
+                  IoTConsensusV2ServerImpl consensus =
+                      new IoTConsensusV2ServerImpl(
+                          new Peer(consensusGroupId, thisNodeId, thisNode),
+                          stateMachine,
+                          new ArrayList<>(),
+                          config,
+                          syncClientManager);
+                  stateMachineMap.put(consensusGroupId, consensus);
+                  checkPeerListAndStartIfEligible(consensusGroupId, consensus);
+                } catch (Exception e) {
                   LOGGER.error(
-                      
IoTConsensusV2Messages.FAILED_RECOVER_CONSENSUS_READ_DIR, storageDir, e);
+                      IoTConsensusV2Messages.FAILED_RECOVER_CONSENSUS,
+                      storageDir,
+                      consensusGroupId,
+                      e);
                 }
-              })
-          .exceptionally(
-              e -> {
-                
LOGGER.error(IoTConsensusV2Messages.FAILED_RECOVER_CONSENSUS_SHORT, storageDir, 
e);
-                return null;
-              });
+              }
+            } catch (IOException e) {
+              
LOGGER.error(IoTConsensusV2Messages.FAILED_RECOVER_CONSENSUS_READ_DIR, 
storageDir, e);
+              throw new CompletionException(e);
+            }
+          });
     }
   }
 
diff --git 
a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2Test.java
 
b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2Test.java
new file mode 100644
index 00000000000..14bdd7205f1
--- /dev/null
+++ 
b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/pipe/IoTConsensusV2Test.java
@@ -0,0 +1,55 @@
+/*
+ * 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.consensus.pipe;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+
+public class IoTConsensusV2Test {
+
+  @Test
+  public void testWaitForRecoveryPropagatesRuntimeException() {
+    IllegalArgumentException cause = new IllegalArgumentException("missing 
DataRegion");
+    CompletableFuture<Void> recoverFuture = new CompletableFuture<>();
+    recoverFuture.completeExceptionally(cause);
+
+    IllegalArgumentException exception =
+        Assert.assertThrows(
+            IllegalArgumentException.class, () -> 
IoTConsensusV2.waitForRecovery(recoverFuture));
+
+    Assert.assertSame(cause, exception);
+  }
+
+  @Test
+  public void 
testWaitForRecoveryPropagatesIOExceptionWrappedByCompletionException() {
+    IOException cause = new IOException("failed to read consensus directory");
+    CompletableFuture<Void> recoverFuture = new CompletableFuture<>();
+    recoverFuture.completeExceptionally(new CompletionException(cause));
+
+    IOException exception =
+        Assert.assertThrows(IOException.class, () -> 
IoTConsensusV2.waitForRecovery(recoverFuture));
+
+    Assert.assertSame(cause, exception);
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
index b5011edc8bd..9b9efc89dd2 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
@@ -371,8 +371,9 @@ public final class DataNodeMiscMessages {
   public static final String SETTING_UP_DATANODE = "Setting up IoTDB 
DataNode...";
   public static final String RECOVER_SCHEMA = "Recover the schema...";
   public static final String DATANODE_FAILED_SETUP = "IoTDB DataNode failed to 
set up.";
-  public static final String WAIT_DATABASES_READY =
-      "Wait for all databases ready, which takes {} ms.";
+  public static final String
+      
MISC_LOG_WAIT_FOR_LOCAL_DATAREGION_RECOVERY_TASKS_TO_FINISH_WHICH_TAKES_ARG_MS_8B33DC6C
 =
+          "Wait for local DataRegion recovery tasks to finish, which takes {} 
ms.";
   public static final String PREPARE_PIPE_RESOURCES =
       "Prepare pipe resources successfully, which takes {} ms.";
   public static final String RECOVER_SCHEMA_SUCCESSFULLY =
diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
index f6971840f5a..4e0e09fe0b7 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
@@ -730,6 +730,7 @@ public final class DataNodeSchemaMessages {
       "This view contains aggregation function(s) named [%s]";
   public static final String EXCEPTION_OPERATORCONTEXT_IS_NULL_D15B1EDB = 
"operatorContext is null";
   public static final String EXCEPTION_CHILD_OPERATOR_IS_NULL_8860113C = 
"child operator is null";
+  public static final String 
EXCEPTION_FAILED_TO_CREATE_STATE_MACHINE_FOR_CONSENSUS_GROUP_ARG_BECAUSE_SCHEMA_REGION_DOES_NOT_EXIST_610DAE67
 = "Failed to create state machine for consensus group %s, because schema 
region does not exist";
   public static final String EXCEPTION_DOT_9D9B854A = ".";
   public static final String EMPTY_MESSAGE = "";
   public static final String EXCEPTION_COMMA_50AD1C01 = ", ";
diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/StorageEngineMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/StorageEngineMessages.java
index fcc7a754704..ffa6c918d48 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/StorageEngineMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/StorageEngineMessages.java
@@ -559,10 +559,11 @@ public final class StorageEngineMessages {
   // 
---------------------------------------------------------------------------
   // Additional log messages
   // 
---------------------------------------------------------------------------
-  public static final String 
STORAGE_LOG_STORAGE_ENGINE_RECOVER_COST_S_C8AEE9D9 =
-      "Storage Engine recover cost: {}s.";
-  public static final String 
STORAGE_LOG_DATA_REGIONS_HAVE_BEEN_RECOVERED_D5BD3A80 =
-      "Data regions have been recovered {}/{}";
+  public static final String
+      
STORAGE_LOG_STORAGE_ENGINE_LOCAL_RECOVERY_TASKS_FINISHED_IN_ARGS_03F9135F =
+          "Storage Engine local recovery tasks finished in {}s.";
+  public static final String 
STORAGE_LOG_LOCAL_DATAREGION_LOADING_PROGRESS_ARG_ARG_8146929B =
+      "Local DataRegion loading progress: {}/{}.";
   public static final String 
STORAGE_LOG_TSFILE_RESOURCE_RECOVER_COST_S_41F074E0 =
       "TsFile Resource recover cost: {}s.";
   public static final String 
STORAGE_LOG_CONSTRUCT_A_DATA_REGION_INSTANCE_THE_DATABASE_IS_THREAD_17A16BDF =
@@ -617,8 +618,6 @@ public final class StorageEngineMessages {
       "The TsFiles of data region {}[{}] has recovered completely {}/{}.";
   public static final String 
STORAGE_LOG_THE_DATA_REGION_IS_CREATED_SUCCESSFULLY_B991F1D4 =
       "The data region {}[{}] is created successfully";
-  public static final String 
STORAGE_LOG_THE_DATA_REGION_IS_RECOVERED_SUCCESSFULLY_5AAFF7B7 =
-      "The data region {}[{}] is recovered successfully";
   public static final String 
STORAGE_LOG_WON_T_INSERT_TABLET_BECAUSE_REGION_IS_DELETED_34D893A7 =
       "Won't insert tablet {}, because region is deleted";
   public static final String 
STORAGE_LOG_ASYNC_CLOSE_TSFILE_FILE_START_TIME_FILE_END_TIME_65020832 =
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
index 8983fd61dc4..1eebea4e388 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeMiscMessages.java
@@ -370,8 +370,9 @@ public final class DataNodeMiscMessages {
   public static final String SETTING_UP_DATANODE = "正在配置 IoTDB DataNode...";
   public static final String RECOVER_SCHEMA = "正在恢复 Schema...";
   public static final String DATANODE_FAILED_SETUP = "IoTDB DataNode 启动失败。";
-  public static final String WAIT_DATABASES_READY =
-      "等待所有数据库就绪,耗时 {} 毫秒。";
+  public static final String
+      
MISC_LOG_WAIT_FOR_LOCAL_DATAREGION_RECOVERY_TASKS_TO_FINISH_WHICH_TAKES_ARG_MS_8B33DC6C
 =
+          "等待本地 DataRegion 恢复任务结束,耗时 {} 毫秒。";
   public static final String PREPARE_PIPE_RESOURCES =
       "Pipe 资源准备完成,耗时 {} 毫秒。";
   public static final String RECOVER_SCHEMA_SUCCESSFULLY =
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
index 9a2ab87eab6..e60932b120a 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
@@ -718,6 +718,7 @@ public final class DataNodeSchemaMessages {
       "该视图包含名为 [%s] 的聚合函数";
   public static final String EXCEPTION_OPERATORCONTEXT_IS_NULL_D15B1EDB = 
"operatorContext 不能为空";
   public static final String EXCEPTION_CHILD_OPERATOR_IS_NULL_8860113C = 
"child operator 不能为空";
+  public static final String 
EXCEPTION_FAILED_TO_CREATE_STATE_MACHINE_FOR_CONSENSUS_GROUP_ARG_BECAUSE_SCHEMA_REGION_DOES_NOT_EXIST_610DAE67
 = "共识组 %s 的状态机创建失败,因为 SchemaRegion 不存在";
   public static final String EXCEPTION_DOT_9D9B854A = ".";
   public static final String EMPTY_MESSAGE = "";
   public static final String EXCEPTION_COMMA_50AD1C01 = ", ";
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/StorageEngineMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/StorageEngineMessages.java
index 19a2e5f68f6..e30108f7a26 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/StorageEngineMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/StorageEngineMessages.java
@@ -559,10 +559,11 @@ public final class StorageEngineMessages {
   // 
---------------------------------------------------------------------------
   // 补充日志消息
   // 
---------------------------------------------------------------------------
-  public static final String 
STORAGE_LOG_STORAGE_ENGINE_RECOVER_COST_S_C8AEE9D9 =
-      "存储引擎恢复耗时:{}s。";
-  public static final String 
STORAGE_LOG_DATA_REGIONS_HAVE_BEEN_RECOVERED_D5BD3A80 =
-      "DataRegion 已恢复 {}/{}";
+  public static final String
+      
STORAGE_LOG_STORAGE_ENGINE_LOCAL_RECOVERY_TASKS_FINISHED_IN_ARGS_03F9135F =
+          "存储引擎本地恢复任务已完成,耗时:{}s。";
+  public static final String 
STORAGE_LOG_LOCAL_DATAREGION_LOADING_PROGRESS_ARG_ARG_8146929B =
+      "本地 DataRegion 加载进度:{}/{}。";
   public static final String 
STORAGE_LOG_TSFILE_RESOURCE_RECOVER_COST_S_41F074E0 =
       "TsFileResource 恢复耗时:{}s。";
   public static final String 
STORAGE_LOG_CONSTRUCT_A_DATA_REGION_INSTANCE_THE_DATABASE_IS_THREAD_17A16BDF =
@@ -613,8 +614,6 @@ public final class StorageEngineMessages {
       "DataRegion {}[{}] 的 TsFiles 已完全恢复 {}/{}。";
   public static final String 
STORAGE_LOG_THE_DATA_REGION_IS_CREATED_SUCCESSFULLY_B991F1D4 =
       "DataRegion {}[{}] 创建成功";
-  public static final String 
STORAGE_LOG_THE_DATA_REGION_IS_RECOVERED_SUCCESSFULLY_5AAFF7B7 =
-      "DataRegion {}[{}] 恢复成功";
   public static final String 
STORAGE_LOG_WON_T_INSERT_TABLET_BECAUSE_REGION_IS_DELETED_34D893A7 =
       "不会插入 tablet {},原因:Region 已删除";
   public static final String 
STORAGE_LOG_ASYNC_CLOSE_TSFILE_FILE_START_TIME_FILE_END_TIME_65020832 =
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/SchemaRegionConsensusImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/SchemaRegionConsensusImpl.java
index f6a1175da19..4fe4570a844 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/SchemaRegionConsensusImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/SchemaRegionConsensusImpl.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType;
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 import org.apache.iotdb.commons.conf.CommonConfig;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
+import org.apache.iotdb.commons.consensus.ConsensusGroupId;
 import org.apache.iotdb.commons.consensus.SchemaRegionId;
 import org.apache.iotdb.consensus.ConsensusFactory;
 import org.apache.iotdb.consensus.IConsensus;
@@ -31,10 +32,14 @@ import org.apache.iotdb.consensus.config.RatisConfig;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import 
org.apache.iotdb.db.consensus.statemachine.schemaregion.SchemaRegionStateMachine;
+import org.apache.iotdb.db.i18n.DataNodeSchemaMessages;
 import org.apache.iotdb.db.schemaengine.SchemaEngine;
+import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegion;
 
 import org.apache.ratis.util.SizeInBytes;
 import org.apache.ratis.util.TimeDuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.concurrent.TimeUnit;
 
@@ -44,6 +49,8 @@ import java.util.concurrent.TimeUnit;
  */
 public class SchemaRegionConsensusImpl {
 
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(SchemaRegionConsensusImpl.class);
+
   private SchemaRegionConsensusImpl() {
     // do nothing
   }
@@ -184,9 +191,7 @@ public class SchemaRegionConsensusImpl {
                               .build())
                       .setStorageDir(CONF.getSchemaRegionConsensusDir())
                       .build(),
-                  gid ->
-                      new SchemaRegionStateMachine(
-                          
SchemaEngine.getInstance().getSchemaRegion((SchemaRegionId) gid)))
+                  
SchemaRegionConsensusImplHolder::createSchemaRegionStateMachine)
               .orElseThrow(
                   () ->
                       new IllegalArgumentException(
@@ -194,5 +199,19 @@ public class SchemaRegionConsensusImpl {
                               ConsensusFactory.CONSTRUCT_FAILED_MSG,
                               CONF.getSchemaRegionConsensusProtocolClass())));
     }
+
+    private static SchemaRegionStateMachine 
createSchemaRegionStateMachine(ConsensusGroupId gid) {
+      ISchemaRegion schemaRegion = 
SchemaEngine.getInstance().getSchemaRegion((SchemaRegionId) gid);
+      if (schemaRegion == null) {
+        String errorMsg =
+            String.format(
+                DataNodeSchemaMessages
+                    
.EXCEPTION_FAILED_TO_CREATE_STATE_MACHINE_FOR_CONSENSUS_GROUP_ARG_BECAUSE_SCHEMA_REGION_DOES_NOT_EXIST_610DAE67,
+                gid);
+        LOGGER.error(errorMsg);
+        throw new IllegalArgumentException(errorMsg);
+      }
+      return new SchemaRegionStateMachine(schemaRegion);
+    }
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java
index 1328aa9e873..48484268623 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/DataNode.java
@@ -190,6 +190,7 @@ public class DataNode extends ServerCommandLine implements 
DataNodeMBean {
 
   private volatile boolean schemaRegionConsensusStarted = false;
   private volatile boolean dataRegionConsensusStarted = false;
+  private long schemaEngineRecoveryTimeInMs;
   private static Thread watcherThread;
   protected DataNodeContext context;
 
@@ -817,12 +818,11 @@ public class DataNode extends ServerCommandLine 
implements DataNodeMBean {
       logger.error(DataNodeMiscMessages.MEET_ERROR_STARTING_UP, e);
       throw e;
     }
-    logger.info(DataNodeMiscMessages.IOTDB_DATANODE_HAS_STARTED);
-
     try {
       long startTime = System.currentTimeMillis();
       SchemaRegionConsensusImpl.getInstance().start();
       long schemaRegionEndTime = System.currentTimeMillis();
+      logger.info(DataNodeMiscMessages.RECOVER_SCHEMA_SUCCESSFULLY, 
schemaEngineRecoveryTimeInMs);
       logger.info(
           DataNodeMiscMessages
               
.MISC_LOG_SCHEMAREGION_CONSENSUS_START_SUCCESSFULLY_WHICH_TAKES_MS_3D1B8523,
@@ -840,6 +840,7 @@ public class DataNode extends ServerCommandLine implements 
DataNodeMBean {
     } catch (IOException e) {
       throw new StartupException(e);
     }
+    logger.info(DataNodeMiscMessages.IOTDB_DATANODE_HAS_STARTED);
   }
 
   void processPid() {
@@ -899,7 +900,10 @@ public class DataNode extends ServerCommandLine implements 
DataNodeMBean {
       }
     }
     long endTime = System.currentTimeMillis();
-    logger.info(DataNodeMiscMessages.WAIT_DATABASES_READY, (endTime - 
startTime));
+    logger.info(
+        DataNodeMiscMessages
+            
.MISC_LOG_WAIT_FOR_LOCAL_DATAREGION_RECOVERY_TASKS_TO_FINISH_WHICH_TAKES_ARG_MS_8B33DC6C,
+        (endTime - startTime));
     // Must init after SchemaEngine and StorageEngine prepared well
     DataNodeRegionManager.getInstance().init();
 
@@ -1333,8 +1337,7 @@ public class DataNode extends ServerCommandLine 
implements DataNodeMBean {
   private void initSchemaEngine() {
     long startTime = System.currentTimeMillis();
     SchemaEngine.getInstance().init();
-    long endTime = System.currentTimeMillis();
-    logger.info(DataNodeMiscMessages.RECOVER_SCHEMA_SUCCESSFULLY, (endTime - 
startTime));
+    schemaEngineRecoveryTimeInMs = System.currentTimeMillis() - startTime;
   }
 
   private void classLoader() {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
index 2062ba70978..b5e4b08c72e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java
@@ -237,7 +237,8 @@ public class StorageEngine implements IService {
               checkResults(futures, 
StorageEngineMessages.STORAGE_ENGINE_FAILED_TO_RECOVER);
               isReadyForReadAndWrite.set(true);
               LOGGER.info(
-                  
StorageEngineMessages.STORAGE_LOG_STORAGE_ENGINE_RECOVER_COST_S_C8AEE9D9,
+                  StorageEngineMessages
+                      
.STORAGE_LOG_STORAGE_ENGINE_LOCAL_RECOVERY_TASKS_FINISHED_IN_ARGS_03F9135F,
                   (System.currentTimeMillis() - startRecoverTime) / 1000);
             },
             ThreadName.STORAGE_ENGINE_RECOVER_TRIGGER.getName());
@@ -267,7 +268,8 @@ public class StorageEngine implements IService {
               }
               dataRegionMap.put(dataRegionId, dataRegion);
               LOGGER.info(
-                  
StorageEngineMessages.STORAGE_LOG_DATA_REGIONS_HAVE_BEEN_RECOVERED_D5BD3A80,
+                  StorageEngineMessages
+                      
.STORAGE_LOG_LOCAL_DATAREGION_LOADING_PROGRESS_ARG_ARG_8146929B,
                   readyDataRegionNum.incrementAndGet(),
                   recoverDataRegionNum);
               return null;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
index 0d14d5b770d..eb63312ebb1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
@@ -787,11 +787,6 @@ public class DataRegion implements IDataRegionForQuery {
           
StorageEngineMessages.STORAGE_LOG_THE_DATA_REGION_IS_CREATED_SUCCESSFULLY_B991F1D4,
           databaseName,
           dataRegionIdString);
-    } else {
-      logger.info(
-          
StorageEngineMessages.STORAGE_LOG_THE_DATA_REGION_IS_RECOVERED_SUCCESSFULLY_5AAFF7B7,
-          databaseName,
-          dataRegionIdString);
     }
   }
 

Reply via email to