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 c818b289e79 Feature/iotconsensus snap multi dir (#16811)
c818b289e79 is described below

commit c818b289e79a05ab0e903a12d81a0bc4bdc45041
Author: Hongzhi Gao <[email protected]>
AuthorDate: Wed Jun 3 16:27:38 2026 +0800

    Feature/iotconsensus snap multi dir (#16811)
    
    * move FolderManager to node-common module
    
    * move FolderManager to node-common module
    
    * Multi-directory snapshot support for IoTConsensus receiver
    
    * Revert "Multi-directory snapshot support for IoTConsensus receiver"
    
    This reverts commit 1fef8e49063f027d7f3c08a3d0689c20523191b0.
    
    * IoTConsensus receiver snapshot multi dirs
    
    * fix imports
    
    * Add keep same disk when loading snapshot
    
    * Use commons i18n for disk messages
    
    * Fix multi directory strategy package prefix
    
    * Fix IoTConsensus snapshot fragment placement
    
    * Use local data dirs for IoTConsensus snapshot receive
    
    * Honor folder availability for same disk selection
    
    ---------
    
    Co-authored-by: luoluoyuyu <[email protected]>
---
 .../iotdb/consensus/config/ConsensusConfig.java    |  15 +++
 .../apache/iotdb/consensus/iot/IoTConsensus.java   |  32 ++++--
 .../consensus/iot/IoTConsensusServerImpl.java      |  96 +++++++++++++----
 .../apache/iotdb/consensus/iot/ReplicateTest.java  |  27 +++++
 .../apache/iotdb/consensus/iot/StabilityTest.java  |   8 ++
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  13 ++-
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |   6 ++
 .../db/consensus/DataRegionConsensusImpl.java      |   2 +
 .../iotconsensusv2/IoTConsensusV2Receiver.java     |   6 +-
 .../protocol/thrift/IoTDBDataNodeReceiver.java     |   6 +-
 .../pipe/sink/util/builder/PipeTsFileBuilder.java  |   6 +-
 .../db/storageengine/dataregion/DataRegion.java    |   2 +-
 .../execute/task/InnerSpaceCompactionTask.java     |   2 +-
 .../impl/SizeTieredCompactionSelector.java         |   2 +-
 .../dataregion/snapshot/SnapshotLoader.java        | 106 ++++++++++---------
 .../tsfile/generator/TsFileNameGenerator.java      |   4 +-
 .../allocation/AbstractNodeAllocationStrategy.java |   6 +-
 .../db/storageengine/load/LoadTsFileManager.java   |   6 +-
 .../storageengine/load/disk/ILoadDiskSelector.java |   2 +-
 .../InheritSystemMultiDisksStrategySelector.java   |   2 +-
 .../db/storageengine/load/disk/MinIOSelector.java  |   2 +-
 .../iotdb/db/storageengine/load/util/LoadUtil.java |   6 +-
 .../db/storageengine/rescon/disk/TierManager.java  |  11 +-
 .../strategy/DirectoryStrategyTest.java            |  10 +-
 .../iotdb/db/storageengine/dataregion/TTLTest.java |   4 +-
 .../BatchedCompactionWithTsFileSplitterTest.java   |  16 ++-
 ...actionWithReadPointPerformerValidationTest.java |   4 +-
 .../utils/CompactionFileGeneratorUtils.java        |   2 +-
 .../utils/MultiTsFileDeviceIteratorTest.java       |   7 +-
 .../dataregion/snapshot/IoTDBSnapshotTest.java     | 115 ++++++++++++++++++---
 .../rescon/disk/FolderManagerTest.java             |   5 +-
 .../conf/iotdb-system.properties.template          |   6 ++
 .../apache/iotdb/commons/i18n/UtilMessages.java    |  12 +++
 .../apache/iotdb/commons/i18n/UtilMessages.java    |  12 +++
 .../apache/iotdb/commons}/disk/FolderManager.java  |  53 +++++++---
 .../commons}/disk/strategy/DirectoryStrategy.java  |  12 +--
 .../disk/strategy/DirectoryStrategyType.java       |   2 +-
 .../strategy/MaxDiskUsableSpaceFirstStrategy.java  |   4 +-
 .../MinFolderOccupiedSpaceFirstStrategy.java       |   8 +-
 .../strategy/RandomOnDiskUsableSpaceStrategy.java  |   4 +-
 .../commons}/disk/strategy/SequenceStrategy.java   |   4 +-
 .../exception/DiskSpaceInsufficientException.java  |   4 +-
 42 files changed, 478 insertions(+), 174 deletions(-)

diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java
index a4bc9852035..f834e41a4c9 100644
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java
+++ 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java
@@ -22,6 +22,7 @@ package org.apache.iotdb.consensus.config;
 import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType;
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
 
+import java.util.List;
 import java.util.Optional;
 
 public class ConsensusConfig {
@@ -29,6 +30,7 @@ public class ConsensusConfig {
   private final TEndPoint thisNodeEndPoint;
   private final int thisNodeId;
   private final String storageDir;
+  private final List<String> recvSnapshotDirs;
   private final TConsensusGroupType consensusGroupType;
   private final RatisConfig ratisConfig;
   private final IoTConsensusConfig iotConsensusConfig;
@@ -38,6 +40,7 @@ public class ConsensusConfig {
       TEndPoint thisNode,
       int thisNodeId,
       String storageDir,
+      List<String> recvSnapshotDirs,
       TConsensusGroupType consensusGroupType,
       RatisConfig ratisConfig,
       IoTConsensusConfig iotConsensusConfig,
@@ -45,6 +48,7 @@ public class ConsensusConfig {
     this.thisNodeEndPoint = thisNode;
     this.thisNodeId = thisNodeId;
     this.storageDir = storageDir;
+    this.recvSnapshotDirs = recvSnapshotDirs;
     this.consensusGroupType = consensusGroupType;
     this.ratisConfig = ratisConfig;
     this.iotConsensusConfig = iotConsensusConfig;
@@ -63,6 +67,10 @@ public class ConsensusConfig {
     return storageDir;
   }
 
+  public List<String> getRecvSnapshotDirs() {
+    return recvSnapshotDirs;
+  }
+
   public TConsensusGroupType getConsensusGroupType() {
     return consensusGroupType;
   }
@@ -88,6 +96,7 @@ public class ConsensusConfig {
     private TEndPoint thisNode;
     private int thisNodeId;
     private String storageDir;
+    private List<String> recvSnapshotDirs;
     private TConsensusGroupType consensusGroupType;
     private RatisConfig ratisConfig;
     private IoTConsensusConfig iotConsensusConfig;
@@ -98,6 +107,7 @@ public class ConsensusConfig {
           thisNode,
           thisNodeId,
           storageDir,
+          recvSnapshotDirs,
           consensusGroupType,
           Optional.ofNullable(ratisConfig).orElseGet(() -> 
RatisConfig.newBuilder().build()),
           Optional.ofNullable(iotConsensusConfig)
@@ -121,6 +131,11 @@ public class ConsensusConfig {
       return this;
     }
 
+    public Builder setRecvSnapshotDirs(List<String> recvSnapshotDirs) {
+      this.recvSnapshotDirs = recvSnapshotDirs;
+      return this;
+    }
+
     public Builder setConsensusGroupType(TConsensusGroupType groupType) {
       this.consensusGroupType = groupType;
       return this;
diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java
index f3895d3edaf..d84f0a5aa81 100644
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java
+++ 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java
@@ -26,6 +26,7 @@ import 
org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory;
 import org.apache.iotdb.commons.concurrent.ThreadName;
 import org.apache.iotdb.commons.concurrent.threadpool.ScheduledExecutorUtil;
 import org.apache.iotdb.commons.consensus.ConsensusGroupId;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.StartupException;
 import org.apache.iotdb.commons.request.IConsensusRequest;
 import org.apache.iotdb.commons.service.RegisterManager;
@@ -94,6 +95,7 @@ public class IoTConsensus implements IConsensus {
   private final TEndPoint thisNode;
   private final int thisNodeId;
   private final File storageDir;
+  private final List<String> recvSnapshotDirs;
   private final IStateMachine.Registry registry;
   private final Map<ConsensusGroupId, IoTConsensusServerImpl> stateMachineMap =
       new ConcurrentHashMap<>();
@@ -110,6 +112,7 @@ public class IoTConsensus implements IConsensus {
     this.thisNode = config.getThisNodeEndPoint();
     this.thisNodeId = config.getThisNodeId();
     this.storageDir = new File(config.getStorageDir());
+    this.recvSnapshotDirs = config.getRecvSnapshotDirs();
     this.config = config.getIotConsensusConfig();
     this.registry = registry;
     this.service = new IoTConsensusRPCService(thisNode, 
config.getIotConsensusConfig());
@@ -177,6 +180,7 @@ public class IoTConsensus implements IConsensus {
           IoTConsensusServerImpl consensus =
               new IoTConsensusServerImpl(
                   path.toString(),
+                  recvSnapshotDirs,
                   new Peer(consensusGroupId, thisNodeId, thisNode),
                   new TreeSet<>(),
                   registry.apply(consensusGroupId),
@@ -186,6 +190,8 @@ public class IoTConsensus implements IConsensus {
                   config);
           stateMachineMap.put(consensusGroupId, consensus);
         }
+      } catch (DiskSpaceInsufficientException e) {
+        throw new IOException(e);
       }
     }
     if (correctPeerListBeforeStart != null) {
@@ -283,16 +289,22 @@ public class IoTConsensus implements IConsensus {
                     return null;
                   }
 
-                  IoTConsensusServerImpl impl =
-                      new IoTConsensusServerImpl(
-                          path,
-                          new Peer(groupId, thisNodeId, thisNode),
-                          new TreeSet<>(peers),
-                          registry.apply(groupId),
-                          backgroundTaskService,
-                          clientManager,
-                          syncClientManager,
-                          config);
+                  IoTConsensusServerImpl impl = null;
+                  try {
+                    impl =
+                        new IoTConsensusServerImpl(
+                            path,
+                            recvSnapshotDirs,
+                            new Peer(groupId, thisNodeId, thisNode),
+                            new TreeSet<>(peers),
+                            registry.apply(groupId),
+                            backgroundTaskService,
+                            clientManager,
+                            syncClientManager,
+                            config);
+                  } catch (DiskSpaceInsufficientException e) {
+                    throw new RuntimeException(e);
+                  }
                   impl.start();
                   return impl;
                 }))
diff --git 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java
 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java
index 74ba871643b..33ff3a4c273 100644
--- 
a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java
+++ 
b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java
@@ -26,6 +26,9 @@ import 
org.apache.iotdb.commons.client.exception.ClientManagerException;
 import org.apache.iotdb.commons.consensus.ConsensusGroupId;
 import org.apache.iotdb.commons.consensus.index.ComparableConsensusRequest;
 import org.apache.iotdb.commons.consensus.index.impl.IoTProgressIndex;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.request.IConsensusRequest;
 import org.apache.iotdb.commons.service.metric.MetricService;
 import org.apache.iotdb.commons.service.metric.PerformanceOverviewMetrics;
@@ -115,6 +118,7 @@ public class IoTConsensusServerImpl {
   private final Lock stateMachineLock = new ReentrantLock();
   private final Condition stateMachineCondition = 
stateMachineLock.newCondition();
   private final String storageDir;
+  private FolderManager recvFolderManager = null;
   private final TreeSet<Peer> configuration;
   private final AtomicLong searchIndex;
   private final LogDispatcher logDispatcher;
@@ -132,15 +136,29 @@ public class IoTConsensusServerImpl {
 
   public IoTConsensusServerImpl(
       String storageDir,
+      List<String> recvSnapshotDirs,
       Peer thisNode,
       TreeSet<Peer> configuration,
       IStateMachine stateMachine,
       ScheduledExecutorService backgroundTaskService,
       IClientManager<TEndPoint, AsyncIoTConsensusServiceClient> clientManager,
       IClientManager<TEndPoint, SyncIoTConsensusServiceClient> 
syncClientManager,
-      IoTConsensusConfig config) {
+      IoTConsensusConfig config)
+      throws DiskSpaceInsufficientException {
     this.active = true;
     this.storageDir = storageDir;
+    List<String> snapshotDirs = new ArrayList<>();
+    if (recvSnapshotDirs != null) {
+      for (String dir : recvSnapshotDirs) {
+        snapshotDirs.add(dir + File.separator + SNAPSHOT_DIR_NAME);
+      }
+    } else {
+      snapshotDirs.add(storageDir);
+    }
+
+    this.recvFolderManager =
+        new FolderManager(
+            snapshotDirs, 
DirectoryStrategyType.MIN_FOLDER_OCCUPIED_SPACE_FIRST_STRATEGY);
     this.thisNode = thisNode;
     this.stateMachine = stateMachine;
     this.cacheQueueMap = new ConcurrentHashMap<>();
@@ -360,18 +378,45 @@ public class IoTConsensusServerImpl {
       throws ConsensusGroupModifyPeerException {
     try {
       String targetFilePath = calculateSnapshotPath(snapshotId, 
originalFilePath);
-      File targetFile = getSnapshotPath(targetFilePath);
-      Path parentDir = Paths.get(targetFile.getParent());
-      if (!Files.exists(parentDir)) {
-        Files.createDirectories(parentDir);
-      }
-      try (FileOutputStream fos = new 
FileOutputStream(targetFile.getAbsolutePath(), true);
-          FileChannel channel = fos.getChannel()) {
-        channel.write(fileChunk.slice(), fileOffset);
+      File existingFile = getExistingSnapshotFile(targetFilePath);
+      if (existingFile != null) {
+        writeSnapshotFragment(existingFile, fileChunk, fileOffset);
+        return;
       }
+
+      recvFolderManager.getNextWithRetry(
+          folder -> {
+            writeSnapshotFragment(getSnapshotPath(folder, targetFilePath), 
fileChunk, fileOffset);
+            return null;
+          });
     } catch (IOException e) {
       throw new ConsensusGroupModifyPeerException(
           String.format(IoTConsensusMessages.ERROR_RECEIVING_SNAPSHOT, 
snapshotId), e);
+    } catch (DiskSpaceInsufficientException e) {
+      throw new ConsensusGroupModifyPeerException(
+          String.format(IoTConsensusMessages.ERROR_RECEIVING_SNAPSHOT, 
snapshotId), e);
+    }
+  }
+
+  private File getExistingSnapshotFile(String targetFilePath) {
+    for (String folder : recvFolderManager.getFolders()) {
+      File targetFile = getSnapshotPath(folder, targetFilePath);
+      if (targetFile.exists()) {
+        return targetFile;
+      }
+    }
+    return null;
+  }
+
+  private void writeSnapshotFragment(File targetFile, ByteBuffer fileChunk, 
long fileOffset)
+      throws IOException {
+    Path parentDir = Paths.get(targetFile.getParent());
+    if (!Files.exists(parentDir)) {
+      Files.createDirectories(parentDir);
+    }
+    try (FileOutputStream fos = new 
FileOutputStream(targetFile.getAbsolutePath(), true);
+        FileChannel channel = fos.getChannel()) {
+      channel.write(fileChunk.slice(), fileOffset);
     }
   }
 
@@ -404,12 +449,17 @@ public class IoTConsensusServerImpl {
 
   public void loadSnapshot(String snapshotId) {
     // TODO: (xingtanzjr) throw exception if the snapshot load failed
-    stateMachine.loadSnapshot(getSnapshotPath(snapshotId));
+    recvFolderManager
+        .getFolders()
+        .forEach(
+            dir -> {
+              stateMachine.loadSnapshot(getSnapshotPath(dir, snapshotId));
+            });
   }
 
-  private File getSnapshotPath(String snapshotRelativePath) {
-    File storageDirFile = new File(storageDir);
-    File snapshotDir = new File(storageDir, snapshotRelativePath);
+  private File getSnapshotPath(String curStorageDir, String 
snapshotRelativePath) {
+    File storageDirFile = new File(curStorageDir);
+    File snapshotDir = new File(curStorageDir, snapshotRelativePath);
     try {
       if (!snapshotDir
           .getCanonicalFile()
@@ -829,15 +879,19 @@ public class IoTConsensusServerImpl {
   }
 
   public void cleanupSnapshot(String snapshotId) throws 
ConsensusGroupModifyPeerException {
-    File snapshotDir = getSnapshotPath(snapshotId);
-    if (snapshotDir.exists()) {
-      try {
-        FileUtils.deleteDirectory(snapshotDir);
-      } catch (IOException e) {
-        throw new ConsensusGroupModifyPeerException(e);
+    List<String> allDirs = new 
ArrayList<>(Collections.singletonList(storageDir));
+    allDirs.addAll(recvFolderManager.getFolders());
+    for (String dir : allDirs) {
+      File snapshotDir = getSnapshotPath(dir, snapshotId);
+      if (snapshotDir.exists()) {
+        try {
+          FileUtils.deleteDirectory(snapshotDir);
+        } catch (IOException e) {
+          throw new ConsensusGroupModifyPeerException(e);
+        }
+      } else {
+        logger.info(IoTConsensusMessages.FILE_NOT_EXIST, snapshotDir);
       }
-    } else {
-      logger.info(IoTConsensusMessages.FILE_NOT_EXIST, snapshotDir);
     }
   }
 
diff --git 
a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java
 
b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java
index f22d3fdadcd..ca96ffec485 100644
--- 
a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java
+++ 
b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java
@@ -71,6 +71,21 @@ public class ReplicateTest {
           new File("target" + File.separator + "2"),
           new File("target" + File.separator + "3"));
 
+  private final List<List<String>> peersRecvSnapshotDirs =
+      Arrays.asList(
+          Arrays.asList(
+              "target" + File.separator + "1-1",
+              "target" + File.separator + "1-2",
+              "target" + File.separator + "1-3"),
+          Arrays.asList(
+              "target" + File.separator + "2-1",
+              "target" + File.separator + "2-2",
+              "target" + File.separator + "2-3"),
+          Arrays.asList(
+              "target" + File.separator + "3-1",
+              "target" + File.separator + "3-2",
+              "target" + File.separator + "3-3"));
+
   private final ConsensusGroup group = new ConsensusGroup(gid, peers);
   private final List<IoTConsensus> servers = new ArrayList<>();
   private final List<TestStateMachine> stateMachines = new ArrayList<>();
@@ -81,6 +96,7 @@ public class ReplicateTest {
       file.mkdirs();
       stateMachines.add(new TestStateMachine());
     }
+    peersRecvSnapshotDirs.forEach(innerList -> innerList.forEach(dir -> new 
File(dir).mkdirs()));
     initServer();
   }
 
@@ -90,6 +106,16 @@ public class ReplicateTest {
     for (File file : peersStorage) {
       FileUtils.deleteFully(file);
     }
+    peersRecvSnapshotDirs.forEach(
+        innerList ->
+            innerList.forEach(
+                dir -> {
+                  try {
+                    FileUtils.deleteFully(new File(dir));
+                  } catch (IOException e) {
+                    throw new RuntimeException(e);
+                  }
+                }));
   }
 
   private void initServer() throws IOException {
@@ -105,6 +131,7 @@ public class ReplicateTest {
                             .setThisNodeId(peers.get(i).getNodeId())
                             .setThisNode(peers.get(i).getEndpoint())
                             
.setStorageDir(peersStorage.get(i).getAbsolutePath())
+                            .setRecvSnapshotDirs(peersRecvSnapshotDirs.get(i))
                             
.setConsensusGroupType(TConsensusGroupType.DataRegion)
                             .build(),
                         groupId -> stateMachines.get(finalI))
diff --git 
a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java
 
b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java
index 1351b674312..9844b2f1e7e 100644
--- 
a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java
+++ 
b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java
@@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -60,6 +61,12 @@ public class StabilityTest {
 
   private final File storageDir = new File("target" + java.io.File.separator + 
"stability");
 
+  private final List<String> recvSnapshotDirs =
+      Arrays.asList(
+          "target" + File.separator + "1-1",
+          "target" + File.separator + "1-2",
+          "target" + File.separator + "1-3");
+
   private IoTConsensus consensusImpl;
 
   private final int basePort = 6667;
@@ -73,6 +80,7 @@ public class StabilityTest {
                         .setThisNodeId(1)
                         .setThisNode(new TEndPoint("0.0.0.0", basePort))
                         .setStorageDir(storageDir.getAbsolutePath())
+                        .setRecvSnapshotDirs(recvSnapshotDirs)
                         .setConsensusGroupType(TConsensusGroupType.DataRegion)
                         .build(),
                     gid -> new TestStateMachine())
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index fbc817d4f61..84fb1fef329 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -87,8 +87,7 @@ public class IoTDBConfig {
   public static final String WATERMARK_GROUPED_LSB = "GroupBasedLSBMethod";
   public static final String CONFIG_NAME = "iotdb-system.properties";
   private static final Logger logger = 
LoggerFactory.getLogger(IoTDBConfig.class);
-  private static final String MULTI_DIR_STRATEGY_PREFIX =
-      "org.apache.iotdb.db.storageengine.rescon.disk.strategy.";
+  private static final String MULTI_DIR_STRATEGY_PREFIX = 
"org.apache.iotdb.commons.disk.strategy.";
   private static final String[] CLUSTER_ALLOWED_MULTI_DIR_STRATEGIES =
       new String[] {"SequenceStrategy", "MaxDiskUsableSpaceFirstStrategy"};
   private static final String DEFAULT_MULTI_DIR_STRATEGY = "SequenceStrategy";
@@ -1219,6 +1218,8 @@ public class IoTDBConfig {
 
   private boolean includeNullValueInWriteThroughputMetric = false;
 
+  private boolean keepSameDiskWhenLoadingSnapshot = false;
+
   private ConcurrentHashMap<String, EncryptParameter> tsFileDBToEncryptMap =
       new ConcurrentHashMap<>(
           Collections.singletonMap("root.__audit", new 
EncryptParameter("UNENCRYPTED", null)));
@@ -4434,6 +4435,14 @@ public class IoTDBConfig {
     this.passwordLockTimeMinutes = passwordLockTimeMinutes;
   }
 
+  public boolean isKeepSameDiskWhenLoadingSnapshot() {
+    return keepSameDiskWhenLoadingSnapshot;
+  }
+
+  public void setKeepSameDiskWhenLoadingSnapshot(boolean 
keepSameDiskWhenLoadingSnapshot) {
+    this.keepSameDiskWhenLoadingSnapshot = keepSameDiskWhenLoadingSnapshot;
+  }
+
   public ConcurrentHashMap<String, EncryptParameter> getTSFileDBToEncryptMap() 
{
     return tsFileDBToEncryptMap;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index 5debbb71972..8cba13b2265 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -1285,6 +1285,12 @@ public class IoTDBDescriptor {
                 "region_migration_speed_limit_bytes_per_second",
                 ConfigurationFileUtils.getConfigurationDefaultValue(
                     "region_migration_speed_limit_bytes_per_second"))));
+    conf.setKeepSameDiskWhenLoadingSnapshot(
+        Boolean.parseBoolean(
+            properties.getProperty(
+                "keep_same_disk_when_loading_snapshot",
+                ConfigurationFileUtils.getConfigurationDefaultValue(
+                    "keep_same_disk_when_loading_snapshot"))));
   }
 
   private void loadIoTConsensusV2Props(TrimProperties properties) throws 
IOException {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java
index e96b7495312..6fc3bbdb596 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java
@@ -55,6 +55,7 @@ import org.apache.ratis.util.TimeDuration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -139,6 +140,7 @@ public class DataRegionConsensusImpl {
           .setThisNodeId(CONF.getDataNodeId())
           .setThisNode(new TEndPoint(CONF.getInternalAddress(), 
CONF.getDataRegionConsensusPort()))
           .setStorageDir(CONF.getDataRegionConsensusDir())
+          .setRecvSnapshotDirs(Arrays.asList(CONF.getLocalDataDirs()))
           .setConsensusGroupType(TConsensusGroupType.DataRegion)
           .setIoTConsensusConfig(
               IoTConsensusConfig.newBuilder()
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java
index 59905e54dad..7d01318c82e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java
@@ -27,6 +27,9 @@ import org.apache.iotdb.commons.consensus.ConsensusGroupId;
 import org.apache.iotdb.commons.consensus.DataRegionId;
 import org.apache.iotdb.commons.consensus.index.ProgressIndex;
 import org.apache.iotdb.commons.consensus.index.ProgressIndexType;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.pipe.receiver.IoTDBReceiverAgent;
 import org.apache.iotdb.commons.pipe.receiver.PipeReceiverFilePathUtils;
 import 
org.apache.iotdb.commons.pipe.sink.payload.iotconsensusv2.request.IoTConsensusV2RequestType;
@@ -45,7 +48,6 @@ import 
org.apache.iotdb.consensus.pipe.IoTConsensusV2ServerImpl;
 import org.apache.iotdb.consensus.pipe.consensuspipe.ConsensusPipeName;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.exception.load.LoadFileException;
 import org.apache.iotdb.db.i18n.DataNodePipeMessages;
 import org.apache.iotdb.db.pipe.consensus.metric.IoTConsensusV2ReceiverMetrics;
@@ -65,8 +67,6 @@ import 
org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus;
 import 
org.apache.iotdb.db.storageengine.dataregion.utils.TableDiskUsageStatisticUtil;
 import org.apache.iotdb.db.storageengine.dataregion.utils.TsFileResourceUtils;
 import org.apache.iotdb.db.storageengine.load.LoadTsFileManager;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
index 37b277efbaf..731c2eb50f0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java
@@ -22,6 +22,9 @@ package org.apache.iotdb.db.pipe.receiver.protocol.thrift;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.audit.IAuditEntity;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import 
org.apache.iotdb.commons.exception.pipe.PipeRuntimeOutOfMemoryCriticalException;
 import org.apache.iotdb.commons.path.PartialPath;
@@ -45,7 +48,6 @@ import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.DataNodePipeMessages;
 import org.apache.iotdb.db.pipe.agent.PipeDataNodeAgent;
 import 
org.apache.iotdb.db.pipe.event.common.schema.PipeSchemaRegionSnapshotEvent;
@@ -103,8 +105,6 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.pipe.PipeEnrichedStatement
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
 import org.apache.iotdb.db.storageengine.load.active.ActiveLoadPathHelper;
 import org.apache.iotdb.db.storageengine.load.util.LoadUtil;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 import org.apache.iotdb.db.tools.schema.SRStatementGenerator;
 import org.apache.iotdb.db.tools.schema.SchemaRegionSnapshotParser;
 import org.apache.iotdb.pipe.api.exception.PipeException;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java
index cd78f4fdbe4..f84c1fe63f1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java
@@ -19,11 +19,11 @@
 
 package org.apache.iotdb.db.pipe.sink.util.builder;
 
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.DataNodePipeMessages;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 import org.apache.iotdb.pipe.api.exception.PipeException;
 
 import org.apache.tsfile.common.constant.TsFileConstant;
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 93a04bf401a..b5113cb4406 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
@@ -29,6 +29,7 @@ import 
org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.file.SystemFileFactory;
 import org.apache.iotdb.commons.path.IFullPath;
@@ -60,7 +61,6 @@ import org.apache.iotdb.db.consensus.DataRegionConsensusImpl;
 import org.apache.iotdb.db.exception.BatchProcessException;
 import org.apache.iotdb.db.exception.DataRegionException;
 import org.apache.iotdb.db.exception.DataTypeInconsistentException;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.exception.TsFileProcessorException;
 import org.apache.iotdb.db.exception.WriteProcessException;
 import org.apache.iotdb.db.exception.WriteProcessRejectException;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java
index 85614ac6457..94b8d7bb016 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java
@@ -19,10 +19,10 @@
 
 package org.apache.iotdb.db.storageengine.dataregion.compaction.execute.task;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.PathUtils;
 import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import org.apache.iotdb.db.service.metrics.CompactionMetrics;
 import org.apache.iotdb.db.service.metrics.FileMetrics;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java
index 41ca9251eff..80b7541df51 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java
@@ -20,9 +20,9 @@
 package org.apache.iotdb.db.storageengine.dataregion.compaction.selector.impl;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.execute.performer.ICompactionPerformer;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.execute.task.InnerSpaceCompactionTask;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java
index 307930cbfbf..c32f2301289 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java
@@ -20,14 +20,14 @@
 package org.apache.iotdb.db.storageengine.dataregion.snapshot;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import org.apache.iotdb.db.storageengine.StorageEngine;
 import org.apache.iotdb.db.storageengine.dataregion.DataRegion;
 import org.apache.iotdb.db.storageengine.dataregion.flush.CompressionRatio;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 
 import org.apache.tsfile.external.commons.io.FileUtils;
 import org.slf4j.Logger;
@@ -315,57 +315,69 @@ public class SnapshotLoader {
     }
   }
 
+  private File createLinksFromSnapshotToSourceDir(
+      String targetSuffix,
+      File file,
+      Map<String, String> fileTarget,
+      String fileKey,
+      String finalDir)
+      throws IOException {
+    File targetFile =
+        new File(finalDir + File.separator + targetSuffix + File.separator + 
file.getName());
+
+    try {
+      if (!targetFile.getParentFile().exists() && 
!targetFile.getParentFile().mkdirs()) {
+        throw new IOException(
+            String.format(
+                "Cannot create directory %s", 
targetFile.getParentFile().getAbsolutePath()));
+      }
+
+      try {
+        Files.createLink(targetFile.toPath(), file.toPath());
+        LOGGER.debug("Created hard link from {} to {}", file, targetFile);
+        fileTarget.put(fileKey, finalDir);
+        return targetFile;
+      } catch (IOException e) {
+        LOGGER.info("Cannot create link from {} to {}, fallback to copy", 
file, targetFile);
+      }
+
+      Files.copy(file.toPath(), targetFile.toPath());
+      fileTarget.put(fileKey, finalDir);
+      return targetFile;
+    } catch (Exception e) {
+      LOGGER.warn(
+          "Failed to process file {} in dir {}: {}", file.getName(), finalDir, 
e.getMessage(), e);
+      throw e;
+    }
+  }
+
   private void createLinksFromSnapshotToSourceDir(
-      String targetSuffix, File[] files, FolderManager folderManager)
-      throws DiskSpaceInsufficientException, IOException {
+      String targetSuffix, File[] files, FolderManager folderManager) throws 
IOException {
     Map<String, String> fileTarget = new HashMap<>();
     for (File file : files) {
       String fileKey = file.getName().split("\\.")[0];
       String dataDir = fileTarget.get(fileKey);
 
+      if (dataDir != null) {
+        createLinksFromSnapshotToSourceDir(targetSuffix, file, fileTarget, 
fileKey, dataDir);
+        continue;
+      }
+
       try {
-        folderManager.getNextWithRetry(
-            currentDataDir -> {
-              String effectiveDir = (dataDir != null) ? dataDir : 
currentDataDir;
-              File targetFile =
-                  new File(
-                      effectiveDir
-                          + File.separator
-                          + targetSuffix
-                          + File.separator
-                          + file.getName());
-
-              try {
-                if (!targetFile.getParentFile().exists() && 
!targetFile.getParentFile().mkdirs()) {
-                  throw new IOException(
-                      String.format(
-                          "Cannot create directory %s",
-                          targetFile.getParentFile().getAbsolutePath()));
-                }
-
-                try {
-                  Files.createLink(targetFile.toPath(), file.toPath());
-                  LOGGER.debug(StorageEngineMessages.CREATED_HARD_LINK, file, 
targetFile);
-                  fileTarget.put(fileKey, effectiveDir);
-                  return targetFile;
-                } catch (IOException e) {
-                  LOGGER.info(
-                      "Cannot create link from {} to {}, fallback to copy", 
file, targetFile);
-                }
-
-                Files.copy(file.toPath(), targetFile.toPath());
-                fileTarget.put(fileKey, effectiveDir);
-                return targetFile;
-              } catch (Exception e) {
-                LOGGER.warn(
-                    "Failed to process file {} in dir {}: {}",
-                    file.getName(),
-                    effectiveDir,
-                    e.getMessage(),
-                    e);
-                throw e;
-              }
-            });
+        String firstFolderOfSameDisk =
+            
IoTDBDescriptor.getInstance().getConfig().isKeepSameDiskWhenLoadingSnapshot()
+                ? 
folderManager.getFirstFolderOfSameDisk(file.getAbsolutePath())
+                : null;
+
+        if (firstFolderOfSameDisk != null) {
+          createLinksFromSnapshotToSourceDir(
+              targetSuffix, file, fileTarget, fileKey, firstFolderOfSameDisk);
+        } else {
+          folderManager.getNextWithRetry(
+              currentDataDir ->
+                  createLinksFromSnapshotToSourceDir(
+                      targetSuffix, file, fileTarget, fileKey, 
currentDataDir));
+        }
       } catch (Exception e) {
         throw new IOException(
             String.format(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java
index 0fbbd5e386f..37c8f1a964f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java
@@ -20,12 +20,12 @@
 package org.apache.iotdb.db.storageengine.dataregion.tsfile.generator;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.TestOnly;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
 import 
org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
 import org.apache.iotdb.db.storageengine.rescon.disk.TierManager;
 
 import org.apache.tsfile.common.constant.TsFileConstant;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java
index 307fab91445..de97bb313f6 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java
@@ -21,13 +21,13 @@ package 
org.apache.iotdb.db.storageengine.dataregion.wal.allocation;
 
 import org.apache.iotdb.commons.conf.CommonConfig;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import org.apache.iotdb.db.storageengine.dataregion.wal.node.IWALNode;
 import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALFakeNode;
 import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALNode;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java
index c43f2b533ab..e3c6948563a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java
@@ -25,6 +25,9 @@ import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.consensus.ConsensusGroupId;
 import org.apache.iotdb.commons.consensus.index.ProgressIndex;
 import org.apache.iotdb.commons.consensus.index.impl.MinimumProgressIndex;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.file.SystemFileFactory;
 import org.apache.iotdb.commons.schema.table.TsFileTableSchemaUtil;
 import org.apache.iotdb.commons.schema.table.TsTable;
@@ -37,7 +40,6 @@ import org.apache.iotdb.commons.utils.RetryUtils;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.consensus.DataRegionConsensusImpl;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.exception.load.LoadFileException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import org.apache.iotdb.db.pipe.agent.PipeDataNodeAgent;
@@ -54,8 +56,6 @@ import 
org.apache.iotdb.db.storageengine.load.active.ActiveLoadAgent;
 import org.apache.iotdb.db.storageengine.load.splitter.ChunkData;
 import org.apache.iotdb.db.storageengine.load.splitter.DeletionData;
 import org.apache.iotdb.db.storageengine.load.splitter.TsFileData;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 import org.apache.iotdb.metrics.utils.MetricLevel;
 
 import com.github.benmanes.caffeine.cache.Cache;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java
index e9216e9b555..b013c7e9ad4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.storageengine.load.disk;
 
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.exception.load.LoadFileException;
 
 import java.io.File;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java
index c56addc4bf9..c937f8fa966 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.storageengine.load.disk;
 
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.exception.load.LoadFileException;
 
 import org.apache.tsfile.fileSystem.FSFactoryProducer;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java
index 8f572fd569b..9be9c98d079 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.storageengine.load.disk;
 
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.exception.load.LoadFileException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import org.apache.iotdb.metrics.utils.FileStoreUtils;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java
index 098a6ac6b49..cafb1b0e700 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java
@@ -19,17 +19,17 @@
 
 package org.apache.iotdb.db.storageengine.load.util;
 
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.RetryUtils;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.v1.ModificationFileV1;
 import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
 import org.apache.iotdb.db.storageengine.load.active.ActiveLoadPathHelper;
 import org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java
index 6929b53c9c7..200be139664 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java
@@ -20,14 +20,15 @@ package org.apache.iotdb.db.storageengine.rescon.disk;
 
 import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.disk.strategy.MaxDiskUsableSpaceFirstStrategy;
+import 
org.apache.iotdb.commons.disk.strategy.MinFolderOccupiedSpaceFirstStrategy;
+import org.apache.iotdb.commons.disk.strategy.RandomOnDiskUsableSpaceStrategy;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.i18n.StorageEngineMessages;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.MaxDiskUsableSpaceFirstStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.MinFolderOccupiedSpaceFirstStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.RandomOnDiskUsableSpaceStrategy;
 import org.apache.iotdb.metrics.utils.FileStoreUtils;
 
 import com.google.common.io.BaseEncoding;
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java
index 1a95ca32768..6343dcc1699 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java
@@ -18,12 +18,12 @@
  */
 package org.apache.iotdb.db.conf.directories.strategy;
 
+import org.apache.iotdb.commons.disk.strategy.MaxDiskUsableSpaceFirstStrategy;
+import 
org.apache.iotdb.commons.disk.strategy.MinFolderOccupiedSpaceFirstStrategy;
+import org.apache.iotdb.commons.disk.strategy.RandomOnDiskUsableSpaceStrategy;
+import org.apache.iotdb.commons.disk.strategy.SequenceStrategy;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.JVMCommonUtils;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.MaxDiskUsableSpaceFirstStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.MinFolderOccupiedSpaceFirstStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.RandomOnDiskUsableSpaceStrategy;
-import org.apache.iotdb.db.storageengine.rescon.disk.strategy.SequenceStrategy;
 import org.apache.iotdb.db.utils.constant.TestConstant;
 
 import org.junit.After;
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java
index c211bc360ad..06ec607a704 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.calc.exception.QueryProcessException;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.NonAlignedFullPath;
@@ -327,7 +328,8 @@ public class TTLTest {
       throws StorageEngineException,
           WriteProcessException,
           IllegalPathException,
-          InterruptedException {
+          InterruptedException,
+          DiskSpaceInsufficientException {
     boolean isEnableCrossCompaction =
         
IoTDBDescriptor.getInstance().getConfig().isEnableCrossSpaceCompaction();
     
IoTDBDescriptor.getInstance().getConfig().setEnableCrossSpaceCompaction(false);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java
index 1ee72fa5f68..5c2bf1c8e43 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.storageengine.dataregion.compaction;
 
 import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.MeasurementPath;
@@ -97,7 +98,8 @@ public class BatchedCompactionWithTsFileSplitterTest extends 
AbstractCompactionT
           InterruptedException,
           MetadataException,
           PageException,
-          LoadFileException {
+          LoadFileException,
+          DiskSpaceInsufficientException {
     TsFileResource seqResource1 =
         generateSingleAlignedSeriesFile(
             "d0",
@@ -132,7 +134,8 @@ public class BatchedCompactionWithTsFileSplitterTest 
extends AbstractCompactionT
           InterruptedException,
           MetadataException,
           PageException,
-          LoadFileException {
+          LoadFileException,
+          DiskSpaceInsufficientException {
     TsFileResource seqResource1 =
         generateSingleAlignedSeriesFile(
             "d0",
@@ -167,7 +170,8 @@ public class BatchedCompactionWithTsFileSplitterTest 
extends AbstractCompactionT
           InterruptedException,
           MetadataException,
           PageException,
-          LoadFileException {
+          LoadFileException,
+          DiskSpaceInsufficientException {
     TsFileResource seqResource1 =
         generateSingleAlignedSeriesFile(
             "d0",
@@ -206,7 +210,8 @@ public class BatchedCompactionWithTsFileSplitterTest 
extends AbstractCompactionT
           InterruptedException,
           MetadataException,
           PageException,
-          LoadFileException {
+          LoadFileException,
+          DiskSpaceInsufficientException {
     TsFileResource seqResource1 =
         generateSingleAlignedSeriesFile(
             "d0",
@@ -319,7 +324,8 @@ public class BatchedCompactionWithTsFileSplitterTest 
extends AbstractCompactionT
           IOException,
           PageException,
           InterruptedException,
-          MetadataException {
+          MetadataException,
+          DiskSpaceInsufficientException {
     TsFileResource targetResource =
         TsFileNameGenerator.getInnerCompactionTargetFileResource(seqResources, 
true);
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java
index b05ab1e633e..7b0c88079d7 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.storageengine.dataregion.compaction.cross;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.AlignedFullPath;
@@ -2101,7 +2102,8 @@ public class 
CrossSpaceCompactionWithReadPointPerformerValidationTest
           WriteProcessException,
           StorageEngineException,
           InterruptedException,
-          MergeException {
+          MergeException,
+          DiskSpaceInsufficientException {
     registerTimeseriesInMManger(5, 10, true);
     createFiles(5, 10, 5, 1000, 0, 0, 100, 100, false, true);
     createFiles(1, 5, 10, 4500, 500, 500, 0, 100, false, false);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java
index 2573a95d1da..fff273adf76 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java
@@ -20,10 +20,10 @@
 package org.apache.iotdb.db.storageengine.dataregion.compaction.utils;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.db.storageengine.dataregion.modification.ModEntry;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.TreeDeletionEntry;
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java
index 1180247a2d3..b5010e60449 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.storageengine.dataregion.compaction.utils;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.AlignedFullPath;
 import org.apache.iotdb.commons.path.IFullPath;
@@ -412,7 +413,8 @@ public class MultiTsFileDeviceIteratorTest extends 
AbstractCompactionTest {
           IOException,
           WriteProcessException,
           StorageEngineException,
-          InterruptedException {
+          InterruptedException,
+          DiskSpaceInsufficientException {
     TSFileDescriptor.getInstance().getConfig().setMaxDegreeOfIndexNode(3);
     int oldAlignedDeviceOffset = TsFileGeneratorUtils.alignDeviceOffset;
     TsFileGeneratorUtils.alignDeviceOffset = 0;
@@ -566,7 +568,8 @@ public class MultiTsFileDeviceIteratorTest extends 
AbstractCompactionTest {
           IOException,
           WriteProcessException,
           StorageEngineException,
-          InterruptedException {
+          InterruptedException,
+          DiskSpaceInsufficientException {
     TSFileDescriptor.getInstance().getConfig().setMaxDegreeOfIndexNode(3);
     int oldAlignedDeviceOffset = TsFileGeneratorUtils.alignDeviceOffset;
     TsFileGeneratorUtils.alignDeviceOffset = 0;
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java
index 7976c14e87a..f2ec78777cd 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.iotdb.db.storageengine.dataregion.snapshot;
 
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
 import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.DataRegionException;
@@ -28,9 +30,7 @@ import 
org.apache.iotdb.db.storageengine.dataregion.DataRegion;
 import org.apache.iotdb.db.storageengine.dataregion.flush.CompressionRatio;
 import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
 import 
org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
 import org.apache.iotdb.db.storageengine.rescon.disk.TierManager;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 
 import org.apache.tsfile.exception.write.WriteProcessException;
@@ -40,17 +40,23 @@ import org.apache.tsfile.utils.TsFileGeneratorUtils;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mockito;
 
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.Method;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import static 
org.apache.iotdb.consensus.iot.IoTConsensusServerImpl.SNAPSHOT_DIR_NAME;
 import static org.apache.tsfile.common.constant.TsFileConstant.PATH_SEPARATOR;
+import static org.junit.Assert.assertEquals;
 
 public class IoTDBSnapshotTest {
   private String[][] testDataDirs =
@@ -69,11 +75,12 @@ public class IoTDBSnapshotTest {
     FileUtils.recursivelyDeleteFolder("target" + File.separator + "tmp");
   }
 
-  private List<TsFileResource> writeTsFiles() throws IOException, 
WriteProcessException {
+  private List<TsFileResource> writeTsFiles(String[] dataDirs)
+      throws IOException, WriteProcessException {
     List<TsFileResource> resources = new ArrayList<>();
     for (int i = 0; i < 100; i++) {
       String filePath =
-          testDataDirs[0][i % 3]
+          dataDirs[i % dataDirs.length]
               + File.separator
               + "sequence"
               + File.separator
@@ -112,7 +119,7 @@ public class IoTDBSnapshotTest {
     IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs);
     TierManager.getInstance().resetFolders();
     try {
-      List<TsFileResource> resources = writeTsFiles();
+      List<TsFileResource> resources = writeTsFiles(testDataDirs[0]);
       DataRegion region = new DataRegion(testSgName, "0");
       region.getTsFileManager().addAll(resources, true);
       File snapshotDir = new File("target" + File.separator + "snapshot");
@@ -121,12 +128,12 @@ public class IoTDBSnapshotTest {
         new 
SnapshotTaker(region).takeFullSnapshot(snapshotDir.getAbsolutePath(), true);
         File[] files =
             snapshotDir.listFiles((dir, name) -> 
name.equals(SnapshotLogger.SNAPSHOT_LOG_NAME));
-        Assert.assertEquals(1, files.length);
+        assertEquals(1, files.length);
         SnapshotLogAnalyzer analyzer = new SnapshotLogAnalyzer(files[0]);
         Assert.assertTrue(analyzer.isSnapshotComplete());
         int cnt = analyzer.getTotalFileCountInSnapshot();
         analyzer.close();
-        Assert.assertEquals(200, cnt);
+        assertEquals(200, cnt);
         for (TsFileResource resource : resources) {
           Assert.assertTrue(resource.tryWriteLock());
         }
@@ -146,7 +153,7 @@ public class IoTDBSnapshotTest {
     IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs);
     TierManager.getInstance().resetFolders();
     try {
-      List<TsFileResource> resources = writeTsFiles();
+      List<TsFileResource> resources = writeTsFiles(testDataDirs[0]);
       resources.subList(50, 100).forEach(x -> 
x.setStatusForTest(TsFileResourceStatus.UNCLOSED));
       DataRegion region = new DataRegion(testSgName, "0");
       region.setAllowCompaction(false);
@@ -157,13 +164,13 @@ public class IoTDBSnapshotTest {
         new 
SnapshotTaker(region).takeFullSnapshot(snapshotDir.getAbsolutePath(), true);
         File[] files =
             snapshotDir.listFiles((dir, name) -> 
name.equals(SnapshotLogger.SNAPSHOT_LOG_NAME));
-        Assert.assertEquals(1, files.length);
+        assertEquals(1, files.length);
         SnapshotLogAnalyzer analyzer = new SnapshotLogAnalyzer(files[0]);
         int cnt = 0;
         Assert.assertTrue(analyzer.isSnapshotComplete());
         cnt = analyzer.getTotalFileCountInSnapshot();
         analyzer.close();
-        Assert.assertEquals(100, cnt);
+        assertEquals(100, cnt);
         for (TsFileResource resource : resources) {
           Assert.assertTrue(resource.tryWriteLock());
         }
@@ -183,7 +190,7 @@ public class IoTDBSnapshotTest {
     IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs);
     TierManager.getInstance().resetFolders();
     try {
-      List<TsFileResource> resources = writeTsFiles();
+      List<TsFileResource> resources = writeTsFiles(testDataDirs[0]);
       DataRegion region = new DataRegion(testSgName, "0");
       CompressionRatio.getInstance().updateRatio(100, 100, "0");
       region.getTsFileManager().addAll(resources, true);
@@ -199,8 +206,8 @@ public class IoTDBSnapshotTest {
                 .loadSnapshotForStateMachine();
         Assert.assertNotNull(dataRegion);
         List<TsFileResource> resource = 
dataRegion.getTsFileManager().getTsFileList(true);
-        Assert.assertEquals(100, resource.size());
-        Assert.assertEquals(
+        assertEquals(100, resource.size());
+        assertEquals(
             new Pair<>(100L, 100L),
             CompressionRatio.getInstance().getDataRegionRatioMap().get("0"));
       } finally {
@@ -212,6 +219,86 @@ public class IoTDBSnapshotTest {
     }
   }
 
+  @Ignore("Need manual execution to specify different disks")
+  @Test
+  public void testLoadSnapshotNoHardLink()
+      throws IOException, WriteProcessException, DirectoryNotLegalException {
+    
IoTDBDescriptor.getInstance().getConfig().setKeepSameDiskWhenLoadingSnapshot(true);
+    // initialize dirs
+    String[][] dataDirsForDB = new String[][] {{"C://snapshot_test", 
"D://snapshot_test"}};
+    File snapshotDir = new File("D://snapshot_store//");
+    if (snapshotDir.exists()) {
+      FileUtils.recursivelyDeleteFolder(snapshotDir.getAbsolutePath());
+    }
+    for (String[] dirs : dataDirsForDB) {
+      for (String dir : dirs) {
+        if (new File(dir).exists()) {
+          FileUtils.recursivelyDeleteFolder(dir);
+        }
+      }
+    }
+    IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(dataDirsForDB);
+    TierManager.getInstance().resetFolders();
+
+    // prepare files, files should be written into two folders
+    List<TsFileResource> resources = writeTsFiles(dataDirsForDB[0]);
+    DataRegion region = new DataRegion(testSgName, "0");
+    region.getTsFileManager().addAll(resources, true);
+
+    // take a snapshot into one disk
+    Assert.assertTrue(snapshotDir.exists() || snapshotDir.mkdirs());
+    try {
+      Assert.assertTrue(
+          new 
SnapshotTaker(region).takeFullSnapshot(snapshotDir.getAbsolutePath(), true));
+      File[] files =
+          snapshotDir.listFiles((dir, name) -> 
name.equals(SnapshotLogger.SNAPSHOT_LOG_NAME));
+      // use loadWithoutLog
+      if (files != null && files.length > 0) {
+        files[0].delete();
+      }
+      // move files to snapshot store (simulate snapshot transfer)
+      for (String dir : dataDirsForDB[0]) {
+        File internalSnapshotDir = new File(dir, SNAPSHOT_DIR_NAME);
+        if (internalSnapshotDir.exists()) {
+          for (File file : FileUtils.listFilesRecursively(internalSnapshotDir, 
f -> true)) {
+            if (file.isFile()) {
+              String absolutePath = file.getAbsolutePath();
+              int snapshotIdIndex = absolutePath.indexOf("snapshot_store");
+              int suffixIndex = snapshotIdIndex + "snapshot_store".length();
+              String suffix = absolutePath.substring(suffixIndex);
+              File snapshotFile = new File(snapshotDir, suffix);
+              FileUtils.copyFile(file, snapshotFile);
+            }
+          }
+        }
+      }
+
+      // load the snapshot
+      DataRegion dataRegion =
+          new SnapshotLoader(snapshotDir.getAbsolutePath(), testSgName, "0")
+              .loadSnapshotForStateMachine();
+      Assert.assertNotNull(dataRegion);
+      resources = dataRegion.getTsFileManager().getTsFileList(true);
+      assertEquals(100, resources.size());
+
+      // files should not be moved to another disk
+      Path snapshotDirPath = snapshotDir.toPath();
+      FileStore snapshotFileStore = Files.getFileStore(snapshotDirPath);
+      for (TsFileResource tsFileResource : resources) {
+        Path tsfilePath = tsFileResource.getTsFile().toPath();
+        FileStore tsFileFileStore = Files.getFileStore(tsfilePath);
+        assertEquals(snapshotFileStore, tsFileFileStore);
+      }
+    } finally {
+      FileUtils.recursivelyDeleteFolder(snapshotDir.getAbsolutePath());
+      for (String[] dirs : dataDirsForDB) {
+        for (String dir : dirs) {
+          FileUtils.recursivelyDeleteFolder(dir);
+        }
+      }
+    }
+  }
+
   @Test
   public void testGetSnapshotFile() throws IOException {
     File tsFile =
@@ -232,7 +319,7 @@ public class IoTDBSnapshotTest {
     Mockito.when(region.getDataRegionIdString()).thenReturn("0");
     File snapshotFile =
         new SnapshotTaker(region).getSnapshotFilePathForTsFile(tsFile, 
"test-snapshotId");
-    Assert.assertEquals(
+    assertEquals(
         new File(
                 IoTDBDescriptor.getInstance().getConfig().getLocalDataDirs()[0]
                     + File.separator
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java
index c8ad437a8c3..52f13c16e64 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java
@@ -19,8 +19,9 @@
 
 package org.apache.iotdb.db.storageengine.rescon.disk;
 
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 
 import org.apache.tsfile.fileSystem.FSFactoryProducer;
 import org.apache.tsfile.fileSystem.fsFactory.FSFactory;
diff --git 
a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
 
b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
index 4d7b5bcea87..531cbac91a8 100644
--- 
a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
+++ 
b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
@@ -1699,6 +1699,12 @@ data_region_iot_max_memory_ratio_for_queue = 0.6
 # Datatype: long
 region_migration_speed_limit_bytes_per_second = 50331648
 
+# When loading snapshot, try keeping TsFiles in the same disk as the snapshot 
dir.
+# This may reduce file copies but may also result in a worse disk load-balance
+# effectiveMode: hot_reload
+# Datatype: boolean
+keep_same_disk_when_loading_snapshot=false
+
 ####################
 ### Blob Allocator Configuration
 ####################
diff --git 
a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java
 
b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java
index 080d30f0948..39f4a6ce931 100644
--- 
a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java
+++ 
b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java
@@ -107,6 +107,18 @@ public final class UtilMessages {
   public static final String UNEXPECTED_ERROR_CHECKING_DISK_SPACE =
       "Unexpected error checking disk space for {}";
 
+  // ======================== FolderManager ========================
+
+  public static final String ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY =
+      "All folders are full, change system mode to read-only.";
+  public static final String FAILED_TO_PROCESS_FOLDER = "Failed to process 
folder {}";
+  public static final String FAILED_TO_READ_FILE_STORE_PATH =
+      "Failed to read file store path '{}'";
+  public static final String DISK_SPACE_INSUFFICIENT_READ_ONLY =
+      "Disk space is insufficient, change system mode to read-only.";
+  public static final String CANNOT_CALCULATE_OCCUPIED_SPACE =
+      "Cannot calculate occupied space of folder {}";
+
   // ======================== NodeUrlUtils ========================
 
   public static final String BAD_CONFIG_NODE_URL = "Bad ConfigNode url: {}";
diff --git 
a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java
 
b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java
index fab9dafe6d2..8fcc938dbfc 100644
--- 
a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java
+++ 
b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java
@@ -105,6 +105,18 @@ public final class UtilMessages {
   public static final String UNEXPECTED_ERROR_CHECKING_DISK_SPACE =
       "检查 {} 的磁盘空间时发生意外错误";
 
+  // ======================== FolderManager ========================
+
+  public static final String ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY =
+      "所有文件夹空间均已耗尽,系统切换为只读模式。";
+  public static final String FAILED_TO_PROCESS_FOLDER = "处理文件夹 {} 失败";
+  public static final String FAILED_TO_READ_FILE_STORE_PATH =
+      "读取文件存储路径 '{}' 失败";
+  public static final String DISK_SPACE_INSUFFICIENT_READ_ONLY =
+      "磁盘空间不足,系统切换为只读模式。";
+  public static final String CANNOT_CALCULATE_OCCUPIED_SPACE =
+      "无法计算文件夹 {} 的已占用空间";
+
   // ======================== NodeUrlUtils ========================
 
   public static final String BAD_CONFIG_NODE_URL = "ConfigNode URL 格式错误:{}";
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManager.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/FolderManager.java
similarity index 72%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManager.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/FolderManager.java
index 77a332152ab..731dc66fa4a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManager.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/FolderManager.java
@@ -17,22 +17,28 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.storageengine.rescon.disk;
+package org.apache.iotdb.commons.disk;
 
 import org.apache.iotdb.commons.cluster.NodeStatus;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
-import org.apache.iotdb.db.i18n.StorageEngineMessages;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.MaxDiskUsableSpaceFirstStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.MinFolderOccupiedSpaceFirstStrategy;
-import 
org.apache.iotdb.db.storageengine.rescon.disk.strategy.RandomOnDiskUsableSpaceStrategy;
-import org.apache.iotdb.db.storageengine.rescon.disk.strategy.SequenceStrategy;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategy;
+import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType;
+import org.apache.iotdb.commons.disk.strategy.MaxDiskUsableSpaceFirstStrategy;
+import 
org.apache.iotdb.commons.disk.strategy.MinFolderOccupiedSpaceFirstStrategy;
+import org.apache.iotdb.commons.disk.strategy.RandomOnDiskUsableSpaceStrategy;
+import org.apache.iotdb.commons.disk.strategy.SequenceStrategy;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.i18n.UtilMessages;
+import org.apache.iotdb.commons.utils.JVMCommonUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -82,7 +88,7 @@ public class FolderManager {
       this.selectStrategy.setFolders(folders);
       this.selectStrategy.setFoldersStates(foldersStates);
     } catch (DiskSpaceInsufficientException e) {
-      logger.error(StorageEngineMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, 
e);
+      logger.error(UtilMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e);
       
CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly);
       
CommonDescriptor.getInstance().getConfig().setStatusReason(NodeStatus.DISK_FULL);
       throw e;
@@ -98,7 +104,7 @@ public class FolderManager {
     try {
       return folders.get(selectStrategy.nextFolderIndex());
     } catch (DiskSpaceInsufficientException e) {
-      logger.error(StorageEngineMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, 
e);
+      logger.error(UtilMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e);
       
CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly);
       
CommonDescriptor.getInstance().getConfig().setStatusReason(NodeStatus.DISK_FULL);
       throw e;
@@ -129,7 +135,7 @@ public class FolderManager {
       try {
         folder = folders.get(selectStrategy.nextFolderIndex());
       } catch (DiskSpaceInsufficientException e) {
-        
logger.error(StorageEngineMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e);
+        logger.error(UtilMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e);
         
CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly);
         
CommonDescriptor.getInstance().getConfig().setStatusReason(NodeStatus.DISK_FULL);
         throw e;
@@ -138,7 +144,7 @@ public class FolderManager {
         return folderConsumer.apply(folder);
       } catch (Exception e) {
         updateFolderState(folder, FolderState.ABNORMAL);
-        logger.warn(StorageEngineMessages.FAILED_TO_PROCESS_FOLDER + folder);
+        logger.warn(UtilMessages.FAILED_TO_PROCESS_FOLDER, folder);
       }
     }
     throw new DiskSpaceInsufficientException(folders);
@@ -147,4 +153,25 @@ public class FolderManager {
   public List<String> getFolders() {
     return folders;
   }
+
+  public String getFirstFolderOfSameDisk(String pathStr) {
+    Path path = Paths.get(pathStr);
+    try {
+      FileStore fileStore = Files.getFileStore(path);
+      for (String folder : folders) {
+        if (foldersStates.getOrDefault(folder, FolderState.ABNORMAL) != 
FolderState.HEALTHY
+            || !JVMCommonUtils.hasSpace(folder)) {
+          continue;
+        }
+        Path folderPath = Paths.get(folder);
+        FileStore folderFileStore = Files.getFileStore(folderPath);
+        if (folderFileStore.equals(fileStore)) {
+          return folder;
+        }
+      }
+    } catch (IOException e) {
+      logger.warn(UtilMessages.FAILED_TO_READ_FILE_STORE_PATH, pathStr, e);
+    }
+    return null;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategy.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategy.java
similarity index 88%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategy.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategy.java
index 0408cf924a4..e8f53ffe4c2 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategy.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategy.java
@@ -16,14 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.storageengine.rescon.disk.strategy;
+package org.apache.iotdb.commons.disk.strategy;
 
 import org.apache.iotdb.commons.cluster.NodeStatus;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
+import org.apache.iotdb.commons.disk.FolderManager;
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.i18n.UtilMessages;
 import org.apache.iotdb.commons.utils.JVMCommonUtils;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
-import org.apache.iotdb.db.i18n.StorageEngineMessages;
-import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,7 +33,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static 
org.apache.iotdb.db.storageengine.rescon.disk.FolderManager.FolderState.HEALTHY;
+import static org.apache.iotdb.commons.disk.FolderManager.FolderState.HEALTHY;
 
 /**
  * The basic class of all the strategies of multiple directories. If a user 
wants to define his own
@@ -61,7 +61,7 @@ public abstract class DirectoryStrategy {
       }
     }
     if (!hasSpace) {
-      LOGGER.error(StorageEngineMessages.DISK_SPACE_INSUFFICIENT_READ_ONLY);
+      LOGGER.error(UtilMessages.DISK_SPACE_INSUFFICIENT_READ_ONLY);
       
CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly);
       throw new DiskSpaceInsufficientException(folders);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategyType.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategyType.java
similarity index 93%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategyType.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategyType.java
index 195ad9c8e72..2d081dd87f5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategyType.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategyType.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.storageengine.rescon.disk.strategy;
+package org.apache.iotdb.commons.disk.strategy;
 
 public enum DirectoryStrategyType {
   SEQUENCE_STRATEGY,
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java
similarity index 92%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java
index dccedaad207..9158027b8a6 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.storageengine.rescon.disk.strategy;
+package org.apache.iotdb.commons.disk.strategy;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.JVMCommonUtils;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 
 public class MaxDiskUsableSpaceFirstStrategy extends DirectoryStrategy {
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java
similarity index 87%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java
index ea2d1909940..d7345eb505c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.storageengine.rescon.disk.strategy;
+package org.apache.iotdb.commons.disk.strategy;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
+import org.apache.iotdb.commons.i18n.UtilMessages;
 import org.apache.iotdb.commons.utils.JVMCommonUtils;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
-import org.apache.iotdb.db.i18n.StorageEngineMessages;
 
 import java.io.IOException;
 
@@ -48,7 +48,7 @@ public class MinFolderOccupiedSpaceFirstStrategy extends 
DirectoryStrategy {
       try {
         space = JVMCommonUtils.getOccupiedSpace(folder);
       } catch (IOException e) {
-        LOGGER.error(StorageEngineMessages.CANNOT_CALC_OCCUPIED_SPACE, folder, 
e);
+        LOGGER.error(UtilMessages.CANNOT_CALCULATE_OCCUPIED_SPACE, folder, e);
         continue;
       }
       if (space < minSpace) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/RandomOnDiskUsableSpaceStrategy.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/RandomOnDiskUsableSpaceStrategy.java
similarity index 94%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/RandomOnDiskUsableSpaceStrategy.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/RandomOnDiskUsableSpaceStrategy.java
index 30c5000396a..28264f142a1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/RandomOnDiskUsableSpaceStrategy.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/RandomOnDiskUsableSpaceStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.storageengine.rescon.disk.strategy;
+package org.apache.iotdb.commons.disk.strategy;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.JVMCommonUtils;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 
 import java.security.SecureRandom;
 import java.util.ArrayList;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/SequenceStrategy.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/SequenceStrategy.java
similarity index 95%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/SequenceStrategy.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/SequenceStrategy.java
index 881623a1882..6b0394e0768 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/SequenceStrategy.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/SequenceStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.storageengine.rescon.disk.strategy;
+package org.apache.iotdb.commons.disk.strategy;
 
+import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException;
 import org.apache.iotdb.commons.utils.JVMCommonUtils;
-import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
 
 import org.apache.tsfile.fileSystem.FSFactoryProducer;
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/DiskSpaceInsufficientException.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/DiskSpaceInsufficientException.java
similarity index 91%
rename from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/DiskSpaceInsufficientException.java
rename to 
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/DiskSpaceInsufficientException.java
index f0b5d587559..20286caea06 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/DiskSpaceInsufficientException.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/DiskSpaceInsufficientException.java
@@ -16,13 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.exception;
+package org.apache.iotdb.commons.exception;
 
 import org.apache.iotdb.rpc.TSStatusCode;
 
 import java.util.List;
 
-public class DiskSpaceInsufficientException extends StorageEngineException {
+public class DiskSpaceInsufficientException extends IoTDBException {
 
   private static final long serialVersionUID = 9001643829368311032L;
 


Reply via email to