This is an automated email from the ASF dual-hosted git repository. shuwenwei pushed a commit to branch cp-pr-18045-dev-1.3 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit e09546ec3507ca76f668664e5ac5d0c28490e398 Author: shuwenwei <[email protected]> AuthorDate: Fri Jun 26 18:25:23 2026 +0800 Add copy fallback for compaction hard links --- .../RepairUnsortedFileCompactionPerformer.java | 9 ++++---- .../task/InsertionCrossSpaceCompactionTask.java | 14 ++++++----- .../dataregion/modification/ModificationFile.java | 3 ++- .../org/apache/iotdb/commons/utils/FileUtils.java | 27 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/performer/impl/RepairUnsortedFileCompactionPerformer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/performer/impl/RepairUnsortedFileCompactionPerformer.java index 18e9ef24df2..534ea471ffa 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/performer/impl/RepairUnsortedFileCompactionPerformer.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/performer/impl/RepairUnsortedFileCompactionPerformer.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.execute.performer.impl; +import org.apache.iotdb.commons.utils.FileUtils; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.CompactionUtils; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.writer.AbstractCompactionWriter; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.writer.RepairUnsortedFileCompactionWriter; @@ -31,7 +32,6 @@ import org.apache.iotdb.db.storageengine.rescon.memory.TsFileResourceManager; import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.Collections; import java.util.List; @@ -74,7 +74,7 @@ public class RepairUnsortedFileCompactionPerformer extends ReadPointCompactionPe private void prepareTargetFile() throws IOException { TsFileResource seqSourceFile = seqFiles.get(0); TsFileResource targetFile = targetFiles.get(0); - Files.createLink(targetFile.getTsFile().toPath(), seqSourceFile.getTsFile().toPath()); + FileUtils.createLink(targetFile.getTsFile().toPath(), seqSourceFile.getTsFile().toPath(), true); ITimeIndex timeIndex = seqSourceFile.getTimeIndex(); if (timeIndex instanceof DeviceTimeIndex) { targetFile.setTimeIndex(timeIndex); @@ -82,9 +82,10 @@ public class RepairUnsortedFileCompactionPerformer extends ReadPointCompactionPe targetFile.setTimeIndex(CompactionUtils.buildDeviceTimeIndex(seqSourceFile)); } if (seqSourceFile.modFileExists()) { - Files.createLink( + FileUtils.createLink( new File(seqSourceFile.getCompactionModFile().getFilePath()).toPath(), - new File(seqSourceFile.getModFile().getFilePath()).toPath()); + new File(seqSourceFile.getModFile().getFilePath()).toPath(), + true); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InsertionCrossSpaceCompactionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InsertionCrossSpaceCompactionTask.java index 992b5406708..e4440ac32f9 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InsertionCrossSpaceCompactionTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InsertionCrossSpaceCompactionTask.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.execute.task; +import org.apache.iotdb.commons.utils.FileUtils; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.service.metrics.FileMetrics; import org.apache.iotdb.db.storageengine.dataregion.compaction.constant.CompactionTaskType; @@ -37,7 +38,6 @@ import org.apache.iotdb.db.storageengine.dataregion.tsfile.generator.TsFileNameG import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -218,14 +218,16 @@ public class InsertionCrossSpaceCompactionTask extends AbstractCompactionTask { private void prepareTargetFiles() throws IOException { File sourceTsFile = unseqFileToInsert.getTsFile(); File targetTsFile = targetFile.getTsFile(); - Files.createLink(targetTsFile.toPath(), sourceTsFile.toPath()); - Files.createLink( + FileUtils.createLink(targetTsFile.toPath(), sourceTsFile.toPath(), true); + FileUtils.createLink( new File(targetTsFile.getPath() + TsFileResource.RESOURCE_SUFFIX).toPath(), - new File(sourceTsFile.getPath() + TsFileResource.RESOURCE_SUFFIX).toPath()); + new File(sourceTsFile.getPath() + TsFileResource.RESOURCE_SUFFIX).toPath(), + true); if (unseqFileToInsert.getModFile().exists()) { - Files.createLink( + FileUtils.createLink( new File(targetTsFile.getPath() + ModificationFile.FILE_SUFFIX).toPath(), - new File(sourceTsFile.getPath() + ModificationFile.FILE_SUFFIX).toPath()); + new File(sourceTsFile.getPath() + ModificationFile.FILE_SUFFIX).toPath(), + true); } targetFile.setProgressIndex(unseqFileToInsert.getMaxProgressIndex()); targetFile.deserialize(); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java index 6489c7e5299..bab214c5974 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.modification; +import org.apache.iotdb.commons.utils.FileUtils; import org.apache.iotdb.db.storageengine.dataregion.modification.io.LocalTextModificationAccessor; import org.apache.iotdb.db.storageengine.dataregion.modification.io.ModificationReader; import org.apache.iotdb.db.storageengine.dataregion.modification.io.ModificationWriter; @@ -180,7 +181,7 @@ public class ModificationFile implements AutoCloseable { File hardlink = new File(filePath + hardlinkSuffix); try { - Files.createLink(Paths.get(hardlink.getAbsolutePath()), Paths.get(filePath)); + FileUtils.createLink(Paths.get(hardlink.getAbsolutePath()), Paths.get(filePath), true); return new ModificationFile(hardlink.getAbsolutePath()); } catch (FileAlreadyExistsException e) { // retry a different name if the file is already created diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java index 557adf43f62..ee5bff42ad6 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java @@ -70,6 +70,33 @@ public class FileUtils { } } + public static void createLink(Path link, Path existing, boolean fallBackToCopy) + throws IOException { + try { + Files.createLink(link, existing); + } catch (IOException e) { + if (!fallBackToCopy) { + throw e; + } + try { + Files.copy(existing, link); + } catch (IOException copyException) { + copyException.addSuppressed(e); + throw copyException; + } + } catch (UnsupportedOperationException e) { + if (!fallBackToCopy) { + throw e; + } + try { + Files.copy(existing, link); + } catch (IOException copyException) { + copyException.addSuppressed(e); + throw copyException; + } + } + } + public static void deleteFileOrDirectory(File file) { deleteFileOrDirectory(file, false); }
