This is an automated email from the ASF dual-hosted git repository. shuwenwei pushed a commit to branch fixBug0609 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 17cce453125eaabad99a2fd53fe919fcdcfc8f1b Author: shuwenwei <[email protected]> AuthorDate: Tue Jun 9 16:01:39 2026 +0800 Fix empty snapshot region migration cleanup --- .../db/storageengine/dataregion/DataRegion.java | 4 ++- .../dataregion/snapshot/SnapshotLoader.java | 10 ++++--- .../tableDiskUsageIndex/TableDiskUsageIndex.java | 31 +++++++++++++--------- .../dataregion/snapshot/IoTDBSnapshotTest.java | 26 ++++++++++++++++++ 4 files changed, 54 insertions(+), 17 deletions(-) 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 7289e83cc9f..0860e7539a1 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 @@ -2201,7 +2201,9 @@ public class DataRegion implements IDataRegionForQuery { databaseName + "-" + dataRegionIdString, systemDir); int regionId = dataRegionId.getId(); - TableDiskUsageIndex.getInstance().remove(databaseName, regionId); + if (isTableModel) { + TableDiskUsageIndex.getInstance().remove(databaseName, regionId); + } FileTimeIndexCacheRecorder.getInstance().removeFileTimeIndexCache(regionId); writeLock("deleteFolder"); try { 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 c32f2301289..ba89bfc6c54 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 @@ -250,6 +250,10 @@ public class SnapshotLoader { private void createLinksFromSnapshotDirToDataDirWithoutLog(File sourceDir) throws IOException, DiskSpaceInsufficientException { + if (!sourceDir.exists()) { + throw new IOException( + String.format("Cannot find snapshot directory %s", sourceDir.getAbsolutePath())); + } File seqFileDir = new File( sourceDir, @@ -267,10 +271,8 @@ public class SnapshotLoader { + File.separator + dataRegionId); if (!seqFileDir.exists() && !unseqFileDir.exists()) { - throw new IOException( - String.format( - "Cannot find %s or %s", - seqFileDir.getAbsolutePath(), unseqFileDir.getAbsolutePath())); + LOGGER.warn("No seq or unseq files in snapshot {}, skip creating file links", sourceDir); + return; } FolderManager folderManager = new FolderManager( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageIndex/TableDiskUsageIndex.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageIndex/TableDiskUsageIndex.java index 40e04fc2678..543356c98bc 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageIndex/TableDiskUsageIndex.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageIndex/TableDiskUsageIndex.java @@ -443,18 +443,25 @@ public class TableDiskUsageIndex { @Override public void apply(TableDiskUsageIndex tableDiskUsageIndex) { - tableDiskUsageIndex.writerMap.computeIfPresent( - regionId, - (k, writer) -> { - if (writer.getActiveReaderNum() > 0) { - // If there are active readers, defer removal until all readers finish - writer.setRemovedFuture(future); - return writer; - } - writer.close(); - future.complete(null); - return null; - }); + DataRegionTableSizeIndexWriter removedWriter = null; + try { + removedWriter = + tableDiskUsageIndex.writerMap.computeIfPresent( + regionId, + (k, writer) -> { + if (writer.getActiveReaderNum() > 0) { + // If there are active readers, defer removal until all readers finish + writer.setRemovedFuture(future); + return writer; + } + writer.close(); + return null; + }); + } finally { + if (removedWriter == null) { + future.complete(null); + } + } } } 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 f2ec78777cd..29fe4f13586 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 @@ -183,6 +183,32 @@ public class IoTDBSnapshotTest { } } + @Test + public void testLoadEmptySnapshotWithoutLog() throws IOException { + String[][] originDataDirs = IoTDBDescriptor.getInstance().getConfig().getTierDataDirs(); + IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs); + TierManager.getInstance().resetFolders(); + File snapshotDir = new File("target" + File.separator + "empty-snapshot"); + try { + if (snapshotDir.exists()) { + FileUtils.recursivelyDeleteFolder(snapshotDir.getAbsolutePath()); + } + Assert.assertTrue(snapshotDir.mkdirs()); + + DataRegion dataRegion = + new SnapshotLoader(snapshotDir.getAbsolutePath(), testSgName, "0") + .loadSnapshotForStateMachine(); + + Assert.assertNotNull(dataRegion); + assertEquals(0, dataRegion.getTsFileManager().getTsFileList(true).size()); + assertEquals(0, dataRegion.getTsFileManager().getTsFileList(false).size()); + } finally { + FileUtils.recursivelyDeleteFolder(snapshotDir.getAbsolutePath()); + IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(originDataDirs); + TierManager.getInstance().resetFolders(); + } + } + @Test public void testLoadSnapshot() throws IOException, WriteProcessException, DataRegionException, DirectoryNotLegalException {
