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

shuwenwei pushed a commit to branch fixLoadSnapshot
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 8e1fb0688ba9755a428c1cb3e3e00f261473812b
Author: shuwenwei <[email protected]>
AuthorDate: Fri May 15 12:02:22 2026 +0800

    Fix snapshot load region replacement
---
 .../dataregion/DataRegionStateMachine.java         | 32 ++++++++++++----------
 .../iotdb/db/storageengine/StorageEngine.java      | 28 +++++++++++++++++++
 .../dataregion/snapshot/SnapshotTaker.java         |  5 ++--
 3 files changed, 48 insertions(+), 17 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java
index 5225f339718..c429a60d8c3 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataRegionStateMachine.java
@@ -123,21 +123,25 @@ public class DataRegionStateMachine extends 
BaseStateMachine {
 
   @Override
   public void loadSnapshot(File latestSnapshotRootDir) {
-    DataRegion newRegion =
-        new SnapshotLoader(
-                latestSnapshotRootDir.getAbsolutePath(),
-                region.getDatabaseName(),
-                region.getDataRegionIdString())
-            .loadSnapshotForStateMachine();
-    if (newRegion == null) {
-      logger.error("Fail to load snapshot from {}", latestSnapshotRootDir);
-      return;
-    }
-    this.region = newRegion;
+    String databaseName = region.getDatabaseName();
+    String dataRegionIdString = region.getDataRegionIdString();
+    DataRegionId regionId = new 
DataRegionId(Integer.parseInt(dataRegionIdString));
     try {
-      StorageEngine.getInstance()
-          .setDataRegion(
-              new 
DataRegionId(Integer.parseInt(region.getDataRegionIdString())), region);
+      DataRegion newRegion =
+          StorageEngine.getInstance()
+              .setDataRegionForSnapshotLoad(
+                  regionId,
+                  () ->
+                      new SnapshotLoader(
+                              latestSnapshotRootDir.getAbsolutePath(),
+                              databaseName,
+                              dataRegionIdString)
+                          .loadSnapshotForStateMachine());
+      if (newRegion == null) {
+        logger.error("Fail to load snapshot from {}", latestSnapshotRootDir);
+        return;
+      }
+      this.region = newRegion;
       ChunkCache.getInstance().clear();
       TimeSeriesMetadataCache.getInstance().clear();
       BloomFilterCache.getInstance().clear();
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 ff294b36ed3..3c84815e546 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
@@ -115,6 +115,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -922,6 +923,33 @@ public class StorageEngine implements IService {
   }
 
   /** This method is not thread-safe */
+  public DataRegion setDataRegionForSnapshotLoad(
+      DataRegionId regionId, Supplier<DataRegion> newRegionSupplier) {
+    if (dataRegionMap.containsKey(regionId)) {
+      DataRegion oldRegion = dataRegionMap.get(regionId);
+      oldRegion.markDeleted();
+      oldRegion.abortCompaction();
+      oldRegion.syncCloseAllWorkingTsFileProcessors();
+      oldRegion.deleteFolder(systemDir);
+      WRITING_METRICS.removeDataRegionMemoryCostMetrics(regionId);
+      WRITING_METRICS.removeFlushingMemTableStatusMetrics(regionId);
+      WRITING_METRICS.removeActiveMemtableCounterMetrics(regionId);
+      FileMetrics.getInstance()
+          .deleteRegion(oldRegion.getDatabaseName(), 
oldRegion.getDataRegionIdString());
+    }
+
+    DataRegion newRegion = newRegionSupplier.get();
+    if (newRegion != null) {
+      WRITING_METRICS.createFlushingMemTableStatusMetrics(regionId);
+      WRITING_METRICS.createDataRegionMemoryCostMetrics(newRegion);
+      WRITING_METRICS.createActiveMemtableCounterMetrics(regionId);
+      dataRegionMap.put(regionId, newRegion);
+    }
+    return newRegion;
+  }
+
+  /** This method is not thread-safe */
+  @TestOnly
   public void setDataRegion(DataRegionId regionId, DataRegion newRegion) {
     if (dataRegionMap.containsKey(regionId)) {
       DataRegion oldRegion = dataRegionMap.get(regionId);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotTaker.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotTaker.java
index f4313827c9a..e8648d6137f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotTaker.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotTaker.java
@@ -271,7 +271,7 @@ public class SnapshotTaker {
     if (!target.getParentFile().exists()) {
       LOGGER.error("Hard link target dir {} doesn't exist", 
target.getParentFile());
     }
-    if (!checkHardLinkSourceFile(source)) {
+    if (!checkHardLinkSourceFile(source, 10)) {
       return;
     }
     Files.deleteIfExists(target.toPath());
@@ -280,8 +280,7 @@ public class SnapshotTaker {
   }
 
   /** For "source file not exists" problem (jira787) debugging */
-  private boolean checkHardLinkSourceFile(File source) {
-    int retry = 10;
+  private boolean checkHardLinkSourceFile(File source, int retry) {
     while (!source.exists() && retry > 0) {
       LOGGER.warn(
           "Hard link source file {} doesn't exist, will retry for {} 
times...", source, retry);

Reply via email to