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

rong 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 61ee2a35bd9 [IOTDB-5869][IOTDB-5721][IOTDB-5901] Load strategy: load 
all files to unsequence dir (#9900)
61ee2a35bd9 is described below

commit 61ee2a35bd9e9a9827f6e94f51a6f4f4fb0f0075
Author: Steve Yurong Su <[email protected]>
AuthorDate: Sun May 21 20:11:47 2023 +0800

    [IOTDB-5869][IOTDB-5721][IOTDB-5901] Load strategy: load all files to 
unsequence dir (#9900)
    
    Cherry-picked from rel/1.1. @yschengzi
    
    - [IOTDB-5869] Load strategy: load all files to unsequence dir (#9837)
    - [IOTDB-5721] Delete TTimePartitionSlotTransmitLimit from 
iotdb-common.properties (#9863)
    - [IOTDB-5901] Load: load tsfile without data will throw NPE (#9894)
    
    ---------
    
    Co-authored-by: yschengzi <[email protected]>
---
 .../org/apache/iotdb/it/utils/TsFileGenerator.java |  42 ++++
 .../org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java  |  18 ++
 .../resources/conf/iotdb-common.properties         |   6 -
 .../apache/iotdb/commons/conf/CommonConfig.java    |   6 +-
 .../iotdb/commons/conf/CommonDescriptor.java       |   8 -
 .../iotdb/db/engine/storagegroup/DataRegion.java   | 268 +++------------------
 .../plan/node/load/LoadSingleTsFileNode.java       |   4 +
 .../plan/scheduler/load/LoadTsFileScheduler.java   |   8 +-
 8 files changed, 105 insertions(+), 255 deletions(-)

diff --git 
a/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java 
b/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java
index c790e0b92fc..3d399862c23 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/it/utils/TsFileGenerator.java
@@ -129,6 +129,48 @@ public class TsFileGenerator implements AutoCloseable {
     logger.info(String.format("Write %d points into device %s", number, 
device));
   }
 
+  public void generateData(
+      String device, int number, long timeGap, boolean isAligned, long 
startTimestamp)
+      throws IOException, WriteProcessException {
+    List<MeasurementSchema> schemas = device2MeasurementSchema.get(device);
+    TreeSet<Long> timeSet = device2TimeSet.get(device);
+    Tablet tablet = new Tablet(device, schemas);
+    long[] timestamps = tablet.timestamps;
+    Object[] values = tablet.values;
+    long sensorNum = schemas.size();
+    long startTime = startTimestamp;
+
+    for (long r = 0; r < number; r++) {
+      int row = tablet.rowSize++;
+      startTime += timeGap;
+      timestamps[row] = startTime;
+      timeSet.add(startTime);
+      for (int i = 0; i < sensorNum; i++) {
+        generateDataPoint(values[i], row, schemas.get(i));
+      }
+      // write
+      if (tablet.rowSize == tablet.getMaxRowNumber()) {
+        if (!isAligned) {
+          writer.write(tablet);
+        } else {
+          writer.writeAligned(tablet);
+        }
+        tablet.reset();
+      }
+    }
+    // write
+    if (tablet.rowSize != 0) {
+      if (!isAligned) {
+        writer.write(tablet);
+      } else {
+        writer.writeAligned(tablet);
+      }
+      tablet.reset();
+    }
+
+    logger.info(String.format("Write %d points into device %s", number, 
device));
+  }
+
   private void generateDataPoint(Object obj, int row, MeasurementSchema 
schema) {
     switch (schema.getType()) {
       case INT32:
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java
index 200f7ca8ba4..5fb44b58a41 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/IOTDBLoadTsFileIT.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.it.framework.IoTDBTestRunner;
 import org.apache.iotdb.it.utils.TsFileGenerator;
 import org.apache.iotdb.itbase.category.ClusterIT;
 import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.jdbc.IoTDBSQLException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.common.Path;
@@ -132,6 +133,8 @@ public class IOTDBLoadTsFileIT {
 
       statement.execute(String.format("delete database %s", 
SchemaConfig.STORAGE_GROUP_0));
       statement.execute(String.format("delete database %s", 
SchemaConfig.STORAGE_GROUP_1));
+    } catch (IoTDBSQLException e) {
+      LOGGER.info(String.format("delete storage group message : %s", 
e.getMessage()));
     }
   }
 
@@ -565,6 +568,21 @@ public class IOTDBLoadTsFileIT {
     }
   }
 
+  @Test
+  public void testLoadWithEmptyTsFile() throws Exception {
+    try (TsFileGenerator generator = new TsFileGenerator(new File(tmpDir, 
"1-0-0-0.tsfile"))) {}
+
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+
+      statement.execute(String.format("load \"%s\"", 
tmpDir.getAbsolutePath()));
+
+      try (ResultSet resultSet = statement.executeQuery("show timeseries")) {
+        Assert.assertFalse(resultSet.next());
+      }
+    }
+  }
+
   private static class SchemaConfig {
     private static final String STORAGE_GROUP_0 = "root.sg.test_0";
     private static final String STORAGE_GROUP_1 = "root.sg.test_1";
diff --git a/node-commons/src/assembly/resources/conf/iotdb-common.properties 
b/node-commons/src/assembly/resources/conf/iotdb-common.properties
index 405a58b161b..6e1087984ee 100644
--- a/node-commons/src/assembly/resources/conf/iotdb-common.properties
+++ b/node-commons/src/assembly/resources/conf/iotdb-common.properties
@@ -84,12 +84,6 @@ cluster_name=defaultCluster
 # Datatype: String
 # 
series_partition_executor_class=org.apache.iotdb.commons.partition.executor.hash.BKDRHashExecutor
 
-# The limit of the TTimePartitionSlot allowed to be transmitted between 
DataNode and ConfigNode
-# Mainly used to balance communication efficiency when loading very large 
TsFile
-# Datatype: Integer
-# time_partition_slot_transmit_limit=1000
-
-
 # The policy of extension SchemaRegionGroup for each Database.
 # These policies are currently supported:
 # 1. CUSTOM(Each Database will allocate schema_region_group_per_database 
RegionGroups as soon as created)
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java 
b/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
index 91c3653cb38..dc985ec877a 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
@@ -120,7 +120,7 @@ public class CommonConfig {
 
   private volatile String statusReason = null;
 
-  private int TTimePartitionSlotTransmitLimit = 1000;
+  private final int TTimePartitionSlotTransmitLimit = 1000;
 
   /** Disk Monitor */
   private double diskSpaceWarningThreshold = 0.05;
@@ -369,10 +369,6 @@ public class CommonConfig {
     return TTimePartitionSlotTransmitLimit;
   }
 
-  public void setTTimePartitionSlotTransmitLimit(int 
TTimePartitionSlotTransmitLimit) {
-    this.TTimePartitionSlotTransmitLimit = TTimePartitionSlotTransmitLimit;
-  }
-
   public boolean isStopping() {
     return isStopping;
   }
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
index d00a1e03dff..5aa42bbe5f0 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonDescriptor.java
@@ -188,14 +188,6 @@ public class CommonDescriptor {
                     String.valueOf(config.getDiskSpaceWarningThreshold()))
                 .trim()));
 
-    config.setTTimePartitionSlotTransmitLimit(
-        Integer.parseInt(
-            properties
-                .getProperty(
-                    "time_partition_slot_transmit_limit",
-                    
String.valueOf(config.getTTimePartitionSlotTransmitLimit()))
-                .trim()));
-
     String endPointUrl =
         properties.getProperty(
             "target_ml_node_endpoint",
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java
index e609ddc4c11..a5a3d7e20be 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java
@@ -2350,16 +2350,9 @@ public class DataRegion implements IDataRegionForQuery {
   }
 
   /**
-   * Load a new tsfile to database processor. Tne file may have overlap with 
other files.
+   * Load a new tsfile to unsequence dir.
    *
-   * <p>that there has no file which is overlapping with the new file.
-   *
-   * <p>Firstly, determine the loading type of the file, whether it needs to 
be loaded in sequence
-   * list or unsequence list.
-   *
-   * <p>Secondly, execute the loading process by the type.
-   *
-   * <p>Finally, update the latestTimeForEachDevice and 
partitionLatestFlushedTimeForEachDevice.
+   * <p>Then, update the latestTimeForEachDevice and 
partitionLatestFlushedTimeForEachDevice.
    *
    * @param newTsFileResource tsfile resource @UsedBy load external tsfile 
module
    * @param deleteOriginFile whether to delete origin tsfile
@@ -2370,43 +2363,31 @@ public class DataRegion implements IDataRegionForQuery {
     long newFilePartitionId = newTsFileResource.getTimePartitionWithCheck();
     writeLock("loadNewTsFile");
     try {
-      List<TsFileResource> sequenceList =
-          
tsFileManager.getOrCreateSequenceListByTimePartition(newFilePartitionId);
-
-      int insertPos = findInsertionPosition(newTsFileResource, sequenceList);
-      LoadTsFileType tsFileType = getLoadingTsFileType(insertPos, 
sequenceList);
-      String renameInfo =
-          (tsFileType == LoadTsFileType.LOAD_SEQUENCE)
-              ? IoTDBConstant.SEQUENCE_FLODER_NAME
-              : IoTDBConstant.UNSEQUENCE_FLODER_NAME;
-      newTsFileResource.setSeq(tsFileType == LoadTsFileType.LOAD_SEQUENCE);
+      newTsFileResource.setSeq(false);
       String newFileName =
-          getLoadingTsFileName(tsFileType, insertPos, newTsFileResource, 
sequenceList);
+          getNewTsFileName(
+              System.currentTimeMillis(),
+              getAndSetNewVersion(newFilePartitionId, newTsFileResource),
+              0,
+              0);
 
       if (!newFileName.equals(tsfileToBeInserted.getName())) {
         logger.info(
-            "TsFile {} must be renamed to {} for loading into the " + 
renameInfo + " list.",
+            "TsFile {} must be renamed to {} for loading into the unsequence 
list.",
             tsfileToBeInserted.getName(),
             newFileName);
         newTsFileResource.setFile(
             fsFactory.getFile(tsfileToBeInserted.getParentFile(), 
newFileName));
       }
-      loadTsFileByType(
-          tsFileType,
-          tsfileToBeInserted,
-          newTsFileResource,
-          newFilePartitionId,
-          insertPos,
-          deleteOriginFile);
-      TsFileMetricManager.getInstance()
-          .addFile(
-              newTsFileResource.getTsFile().length(), tsFileType == 
LoadTsFileType.LOAD_SEQUENCE);
+      loadTsFileToUnSequence(
+          tsfileToBeInserted, newTsFileResource, newFilePartitionId, 
deleteOriginFile);
+      
TsFileMetricManager.getInstance().addFile(newTsFileResource.getTsFile().length(),
 false);
 
       resetLastCacheWhenLoadingTsFile(); // update last cache
       updateLastFlushTime(newTsFileResource); // update last flush time
       long partitionNum = newTsFileResource.getTimePartition();
       updatePartitionFileVersion(partitionNum, newTsFileResource.getVersion());
-      logger.info("TsFile {} is successfully loaded in {} list.", newFileName, 
renameInfo);
+      logger.info("TsFile {} is successfully loaded in unsequence list.", 
newFileName);
     } catch (DiskSpaceInsufficientException e) {
       logger.error(
           "Failed to append the tsfile {} to database processor {} because the 
disk space is insufficient.",
@@ -2437,104 +2418,6 @@ public class DataRegion implements IDataRegionForQuery {
     return Math.max(oldVersion, newVersion);
   }
 
-  private Long getTsFileResourceEstablishTime(TsFileResource tsFileResource) {
-    String tsFileName = tsFileResource.getTsFile().getName();
-    return Long.parseLong(tsFileName.split(FILE_NAME_SEPARATOR)[0]);
-  }
-
-  private LoadTsFileType getLoadingTsFileType(int insertPos, 
List<TsFileResource> sequenceList) {
-    if (insertPos == POS_OVERLAP) {
-      return LoadTsFileType.LOAD_UNSEQUENCE;
-    }
-    if (insertPos == sequenceList.size() - 1) {
-      return LoadTsFileType.LOAD_SEQUENCE;
-    }
-    long preTime =
-        (insertPos == -1) ? 0 : 
getTsFileResourceEstablishTime(sequenceList.get(insertPos));
-    long subsequenceTime = 
getTsFileResourceEstablishTime(sequenceList.get(insertPos + 1));
-    return preTime == subsequenceTime
-        ? LoadTsFileType.LOAD_UNSEQUENCE
-        : LoadTsFileType.LOAD_SEQUENCE;
-  }
-
-  /**
-   * Find the position of "newTsFileResource" in the sequence files if it can 
be inserted into them.
-   *
-   * @return POS_ALREADY_EXIST(- 2) if some file has the same name as the one 
to be inserted
-   *     POS_OVERLAP(-3) if some file overlaps the new file an insertion 
position i >= -1 if the new
-   *     file can be inserted between [i, i+1]
-   */
-  private int findInsertionPosition(
-      TsFileResource newTsFileResource, List<TsFileResource> sequenceList) {
-
-    int insertPos = -1;
-
-    // find the position where the new file should be inserted
-    for (int i = 0; i < sequenceList.size(); i++) {
-      TsFileResource localFile = sequenceList.get(i);
-
-      if (!localFile.isClosed() && localFile.getProcessor() != null) {
-        // we cannot compare two files by TsFileResource unless they are both 
closed
-        syncCloseOneTsFileProcessor(true, localFile.getProcessor());
-      }
-      int fileComparison = compareTsFileDevices(newTsFileResource, localFile);
-      switch (fileComparison) {
-        case 0:
-          // some devices are newer but some devices are older, the two files 
overlap in general
-          return POS_OVERLAP;
-        case -1:
-          // all devices in localFile are newer than the new file, the new 
file can be
-          // inserted before localFile
-          return i - 1;
-        default:
-          // all devices in the local file are older than the new file, 
proceed to the next file
-          insertPos = i;
-      }
-    }
-    return insertPos;
-  }
-
-  /**
-   * Compare each device in the two files to find the time relation of them.
-   *
-   * @return -1 if fileA is totally older than fileB (A < B) 0 if fileA is 
partially older than
-   *     fileB and partially newer than fileB (A X B) 1 if fileA is totally 
newer than fileB (B < A)
-   */
-  private int compareTsFileDevices(TsFileResource fileA, TsFileResource fileB) 
{
-    boolean hasPre = false, hasSubsequence = false;
-    Set<String> fileADevices = fileA.getDevices();
-    Set<String> fileBDevices = fileB.getDevices();
-    for (String device : fileADevices) {
-      if (!fileBDevices.contains(device)) {
-        continue;
-      }
-      long startTimeA = fileA.getStartTime(device);
-      long endTimeA = fileA.getEndTime(device);
-      long startTimeB = fileB.getStartTime(device);
-      long endTimeB = fileB.getEndTime(device);
-      if (startTimeA > endTimeB) {
-        // A's data of the device is later than to the B's data
-        hasPre = true;
-      } else if (startTimeB > endTimeA) {
-        // A's data of the device is previous to the B's data
-        hasSubsequence = true;
-      } else {
-        // the two files overlap in the device
-        return 0;
-      }
-    }
-    if (hasPre && hasSubsequence) {
-      // some devices are newer but some devices are older, the two files 
overlap in general
-      return 0;
-    }
-    if (!hasPre && hasSubsequence) {
-      // all devices in B are newer than those in A
-      return -1;
-    }
-    // all devices in B are older than those in A
-    return 1;
-  }
-
   /**
    * If the historical versions of a file is a sub-set of the given file's, 
(close and) remove it to
    * reduce unnecessary merge. Only used when the file sender and the receiver 
share the same file
@@ -2614,50 +2497,6 @@ public class DataRegion implements IDataRegionForQuery {
     tsFileResource.remove();
   }
 
-  /**
-   * Get an appropriate filename to ensure the order between files. The tsfile 
is named after
-   * 
({systemTime}-{versionNum}-{in_space_compaction_num}-{cross_space_compaction_num}.tsfile).
-   *
-   * <p>The sorting rules for tsfile names @see {@link this#compareFileName}, 
we can restore the
-   * list based on the file name and ensure the correctness of the order, so 
there are three cases.
-   *
-   * <p>1. The tsfile is to be inserted in the first place of the list. 
Timestamp can be set to half
-   * of the timestamp value in the file name of the first tsfile in the list , 
and the version
-   * number will be updated to the largest number in this time partition.
-   *
-   * <p>2. The tsfile is to be inserted in the last place of the list. The 
file name is generated by
-   * the system according to the naming rules and returned.
-   *
-   * <p>3. This file is inserted between two files. The time stamp is the mean 
of the timestamps of
-   * the two files, the version number will be updated to the largest number 
in this time partition.
-   *
-   * @param insertIndex the new file will be inserted between the files 
[insertIndex, insertIndex +
-   *     1]
-   * @return appropriate filename
-   */
-  private String getLoadingTsFileName(
-      LoadTsFileType tsFileType,
-      int insertIndex,
-      TsFileResource newTsFileResource,
-      List<TsFileResource> sequenceList) {
-    long timePartitionId = newTsFileResource.getTimePartition();
-    if (tsFileType == LoadTsFileType.LOAD_UNSEQUENCE || insertIndex == 
sequenceList.size() - 1) {
-      return getNewTsFileName(
-          System.currentTimeMillis(),
-          getAndSetNewVersion(timePartitionId, newTsFileResource),
-          0,
-          0);
-    }
-
-    long preTime =
-        (insertIndex == -1) ? 0 : 
getTsFileResourceEstablishTime(sequenceList.get(insertIndex));
-    long subsequenceTime = 
getTsFileResourceEstablishTime(sequenceList.get(insertIndex + 1));
-    long meanTime = preTime + ((subsequenceTime - preTime) >> 1);
-
-    return getNewTsFileName(
-        meanTime, getAndSetNewVersion(timePartitionId, newTsFileResource), 0, 
0);
-  }
-
   private long getAndSetNewVersion(long timePartitionId, TsFileResource 
tsFileResource) {
     long version = partitionMaxFileVersions.getOrDefault(timePartitionId, 0L) 
+ 1;
     partitionMaxFileVersions.put(timePartitionId, version);
@@ -2681,74 +2520,38 @@ public class DataRegion implements IDataRegionForQuery {
   /**
    * Execute the loading process by the type.
    *
-   * @param type load type
    * @param tsFileResource tsfile resource to be loaded
    * @param filePartitionId the partition id of the new file
    * @param deleteOriginFile whether to delete the original file
    * @return load the file successfully @UsedBy sync module, load external 
tsfile module.
    */
-  private boolean loadTsFileByType(
-      LoadTsFileType type,
+  private boolean loadTsFileToUnSequence(
       File tsFileToLoad,
       TsFileResource tsFileResource,
       long filePartitionId,
-      int insertPos,
       boolean deleteOriginFile)
       throws LoadFileException, DiskSpaceInsufficientException {
     File targetFile;
-    switch (type) {
-      case LOAD_UNSEQUENCE:
-        targetFile =
-            fsFactory.getFile(
-                
DirectoryManager.getInstance().getNextFolderForUnSequenceFile(),
-                databaseName
-                    + File.separatorChar
-                    + dataRegionId
-                    + File.separatorChar
-                    + filePartitionId
-                    + File.separator
-                    + tsFileResource.getTsFile().getName());
-        tsFileResource.setFile(targetFile);
-        if (tsFileManager.contains(tsFileResource, false)) {
-          logger.error("The file {} has already been loaded in unsequence 
list", tsFileResource);
-          return false;
-        }
-        tsFileManager.add(tsFileResource, false);
-        logger.info(
-            "Load tsfile in unsequence list, move file from {} to {}",
-            tsFileToLoad.getAbsolutePath(),
-            targetFile.getAbsolutePath());
-        break;
-      case LOAD_SEQUENCE:
-        targetFile =
-            fsFactory.getFile(
-                DirectoryManager.getInstance().getNextFolderForSequenceFile(),
-                databaseName
-                    + File.separatorChar
-                    + dataRegionId
-                    + File.separatorChar
-                    + filePartitionId
-                    + File.separator
-                    + tsFileResource.getTsFile().getName());
-        tsFileResource.setFile(targetFile);
-        if (tsFileManager.contains(tsFileResource, true)) {
-          logger.error("The file {} has already been loaded in sequence list", 
tsFileResource);
-          return false;
-        }
-        if (insertPos == -1) {
-          tsFileManager.insertToPartitionFileList(tsFileResource, 
filePartitionId, true, 0);
-        } else {
-          tsFileManager.insertToPartitionFileList(
-              tsFileResource, filePartitionId, true, insertPos + 1);
-        }
-        logger.info(
-            "Load tsfile in sequence list, move file from {} to {}",
-            tsFileToLoad.getAbsolutePath(),
-            targetFile.getAbsolutePath());
-        break;
-      default:
-        throw new LoadFileException(String.format("Unsupported type of loading 
tsfile : %s", type));
+    targetFile =
+        fsFactory.getFile(
+            DirectoryManager.getInstance().getNextFolderForUnSequenceFile(),
+            databaseName
+                + File.separatorChar
+                + dataRegionId
+                + File.separatorChar
+                + filePartitionId
+                + File.separator
+                + tsFileResource.getTsFile().getName());
+    tsFileResource.setFile(targetFile);
+    if (tsFileManager.contains(tsFileResource, false)) {
+      logger.error("The file {} has already been loaded in unsequence list", 
tsFileResource);
+      return false;
     }
+    tsFileManager.add(tsFileResource, false);
+    logger.info(
+        "Load tsfile in unsequence list, move file from {} to {}",
+        tsFileToLoad.getAbsolutePath(),
+        targetFile.getAbsolutePath());
 
     // move file from sync dir to data dir
     if (!targetFile.getParentFile().exists()) {
@@ -3376,11 +3179,6 @@ public class DataRegion implements IDataRegionForQuery {
     this.tsFileManager.setAllowCompaction(allowCompaction);
   }
 
-  private enum LoadTsFileType {
-    LOAD_SEQUENCE,
-    LOAD_UNSEQUENCE
-  }
-
   @FunctionalInterface
   public interface CloseTsFileCallBack {
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/load/LoadSingleTsFileNode.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/load/LoadSingleTsFileNode.java
index fdc15a0320b..d68184b04d3 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/load/LoadSingleTsFileNode.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/load/LoadSingleTsFileNode.java
@@ -69,6 +69,10 @@ public class LoadSingleTsFileNode extends WritePlanNode {
     this.deleteAfterLoad = deleteAfterLoad;
   }
 
+  public boolean isTsFileEmpty() {
+    return resource.getDevices().isEmpty();
+  }
+
   public boolean needDecodeTsFile(
       Function<List<Pair<String, TTimePartitionSlot>>, 
List<TRegionReplicaSet>> partitionFetcher)
       throws IOException {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
index 435768c1d27..bf37b748587 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/scheduler/load/LoadTsFileScheduler.java
@@ -135,7 +135,13 @@ public class LoadTsFileScheduler implements IScheduler {
       LoadSingleTsFileNode node = tsFileNodeList.get(i);
       boolean isLoadSingleTsFileSuccess = true;
       try {
-        if (!node.needDecodeTsFile(
+        if (node.isTsFileEmpty()) {
+          logger.info(
+              String.format(
+                  "Load skip TsFile %s, because it has no data.",
+                  node.getTsFileResource().getTsFilePath()));
+
+        } else if (!node.needDecodeTsFile(
             partitionFetcher::queryDataPartition)) { // do not decode, load 
locally
           isLoadSingleTsFileSuccess = loadLocally(node);
           node.clean();

Reply via email to