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 3ea1fc666ac Delete empty TsFile sidecars after LOAD (#18599)
3ea1fc666ac is described below

commit 3ea1fc666acd69d94d119a18b1a44b1016b2af16
Author: Zhenyu Luo <[email protected]>
AuthorDate: Fri Sep 11 09:58:44 2026 +0800

    Delete empty TsFile sidecars after LOAD (#18599)
    
    When LOAD skips an empty TsFile with on-success=delete, also remove its 
resource and mods files, and add an integration test covering the deletion.
---
 .../org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java  | 27 ++++++++++++++++++++++
 .../plan/analyze/load/LoadTsFileAnalyzer.java      | 20 +++++++++++++++-
 2 files changed, 46 insertions(+), 1 deletion(-)

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 fa5e0ecc313..6640277eddb 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,8 @@ import 
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
 import org.apache.iotdb.db.it.utils.TestUtils;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.TreeDeletionEntry;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.v1.ModificationFileV1;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
 import org.apache.iotdb.it.env.EnvFactory;
 import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper;
 import org.apache.iotdb.it.framework.IoTDBTestRunner;
@@ -1010,6 +1012,31 @@ public class IoTDBLoadTsFileIT {
     }
   }
 
+  @Test
+  public void testDeleteEmptyTsFileAfterLoad() throws Exception {
+    final File tsFile = new File(tmpDir, "empty-1-0-0-0.tsfile");
+    try (final TsFileGenerator ignored = new TsFileGenerator(tsFile)) {}
+
+    final File resourceFile = new File(tsFile.getAbsolutePath() + 
TsFileResource.RESOURCE_SUFFIX);
+    final File modsFile = ModificationFile.getExclusiveMods(tsFile);
+    final File modsV1File = new File(tsFile.getAbsolutePath() + 
ModificationFileV1.FILE_SUFFIX);
+
+    Assert.assertTrue(resourceFile.createNewFile());
+    Assert.assertTrue(modsFile.createNewFile());
+    Assert.assertTrue(modsV1File.createNewFile());
+
+    try (final Connection connection = EnvFactory.getEnv().getConnection();
+        final Statement statement = connection.createStatement()) {
+      statement.execute(
+          String.format("load \"%s\" with ('on-success'='delete')", 
tsFile.getAbsolutePath()));
+
+      Assert.assertFalse(tsFile.exists());
+      Assert.assertFalse(resourceFile.exists());
+      Assert.assertFalse(modsFile.exists());
+      Assert.assertFalse(modsV1File.exists());
+    }
+  }
+
   @Test
   public void testAsyncLoadKeepsSameNamedTsFilesWithModsIsolated() throws 
Exception {
     registerSchema();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzer.java
index 8e92e00c280..52ab6f5ebd2 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/load/LoadTsFileAnalyzer.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.commons.exception.SemanticException;
 import org.apache.iotdb.commons.queryengine.common.SessionInfo;
 import org.apache.iotdb.commons.queryengine.common.SqlDialect;
 import org.apache.iotdb.commons.queryengine.utils.TimestampPrecisionUtils;
+import org.apache.iotdb.commons.utils.RetryUtils;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.load.LoadAnalyzeException;
 import org.apache.iotdb.db.exception.load.LoadAnalyzeInvalidPathException;
@@ -43,6 +44,7 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LoadTsFile;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.LoadTsFileStatement;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile;
 import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
 import 
org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus;
 import org.apache.iotdb.db.storageengine.dataregion.utils.TsFileResourceUtils;
@@ -69,6 +71,7 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.BufferUnderflowException;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -490,7 +493,10 @@ public class LoadTsFileAnalyzer implements AutoCloseable {
           
DataNodeQueryMessages.EMPTY_FILE_DETECTED_WILL_SKIP_LOADING_THIS_FILE,
           tsFile.getAbsolutePath());
       if (isDeleteAfterLoad) {
-        org.apache.iotdb.commons.utils.FileUtils.deleteFileIfExist(tsFile);
+        deleteFile(tsFile);
+        deleteFile(new 
File(LoadUtil.getTsFileResourcePath(tsFile.getAbsolutePath())));
+        deleteFile(ModificationFile.getExclusiveMods(tsFile));
+        deleteFile(new 
File(LoadUtil.getTsFileModsV1Path(tsFile.getAbsolutePath())));
       }
     } finally {
       // reset the session info to the original one
@@ -498,6 +504,18 @@ public class LoadTsFileAnalyzer implements AutoCloseable {
     }
   }
 
+  private void deleteFile(final File file) {
+    try {
+      RetryUtils.retryOnException(
+          () -> {
+            Files.deleteIfExists(file.toPath());
+            return null;
+          });
+    } catch (final Exception e) {
+      LOGGER.warn(DataNodeQueryMessages.DELETE_AFTER_LOADING_ERROR, file, e);
+    }
+  }
+
   private boolean handleSingleMiniFile(final int i) throws 
FileNotFoundException {
     final long startTime = System.nanoTime();
     try {

Reply via email to