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 35e36d58f587a2b8fa77b681804ee6891a51812b Author: shuwenwei <[email protected]> AuthorDate: Tue Jun 9 16:01:39 2026 +0800 Fix empty snapshot loading and region cleanup Allow loading snapshots that do not contain seq or unseq data directories so empty regions can be migrated successfully. Skip table disk usage index removal for tree-model regions and complete remove operations when no writer exists to avoid delete-region timeouts. --- .../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 {
