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 {