From 5f0ad8c069cee5299bb3ef27074f38ab16c3c2cb Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Thu, 4 Dec 2025 22:41:41 +0800 Subject: [PATCH 1/8] fix Signed-off-by: OneSizeFitsQuorum --- .../wal/allocation/AbstractNodeAllocationStrategy.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java index 119f262ea660..ade9fad13562 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java @@ -57,6 +57,10 @@ protected AbstractNodeAllocationStrategy() { protected IWALNode createWALNode(String identifier) { try { + if (folderManager == null) { + folderManager = new FolderManager( + Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY); + } return folderManager.getNextWithRetry( folder -> new WALNode(identifier, folder + File.separator + identifier)); } catch (DiskSpaceInsufficientException e) { From cd69d063e4592c7cdb93f2cb1ebf5d0816ee9cf8 Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Thu, 4 Dec 2025 23:04:10 +0800 Subject: [PATCH 2/8] finish Signed-off-by: OneSizeFitsQuorum --- .../AbstractNodeAllocationStrategy.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java index ade9fad13562..68d4e39876a1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java @@ -34,6 +34,7 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicReference; public abstract class AbstractNodeAllocationStrategy implements NodeAllocationStrategy { private static final Logger logger = @@ -41,13 +42,13 @@ public abstract class AbstractNodeAllocationStrategy implements NodeAllocationSt private static final CommonConfig commonConfig = CommonDescriptor.getInstance().getConfig(); // manage wal folders - protected FolderManager folderManager; + protected AtomicReference folderManager = new AtomicReference<>(); protected AbstractNodeAllocationStrategy() { try { - folderManager = + folderManager.set( new FolderManager( - Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY); + Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY)); } catch (DiskSpaceInsufficientException e) { logger.error( "Fail to create wal node allocation strategy because all disks of wal folders are full.", @@ -57,12 +58,16 @@ protected AbstractNodeAllocationStrategy() { protected IWALNode createWALNode(String identifier) { try { - if (folderManager == null) { - folderManager = new FolderManager( - Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY); + // already in lock, so no need to synchronized + if (folderManager.get() == null) { + folderManager.set( + new FolderManager( + Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY)); } - return folderManager.getNextWithRetry( - folder -> new WALNode(identifier, folder + File.separator + identifier)); + return folderManager + .get() + .getNextWithRetry( + folder -> new WALNode(identifier, folder + File.separator + identifier)); } catch (DiskSpaceInsufficientException e) { logger.error("Fail to create wal node because all disks of wal folders are full.", e); return WALFakeNode.getFailureInstance(e); From fdf0e8fc4f9b9fa299db998dfb79bddf3157e75b Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Sat, 13 Dec 2025 09:45:36 +0800 Subject: [PATCH 3/8] add test & synchronized Signed-off-by: OneSizeFitsQuorum --- .../AbstractNodeAllocationStrategy.java | 31 +++----- .../allocation/FirstCreateStrategyTest.java | 74 +++++++++++++++++++ 2 files changed, 83 insertions(+), 22 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java index 68d4e39876a1..9fdba1b14c41 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java @@ -34,7 +34,6 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; -import java.util.concurrent.atomic.AtomicReference; public abstract class AbstractNodeAllocationStrategy implements NodeAllocationStrategy { private static final Logger logger = @@ -42,13 +41,13 @@ public abstract class AbstractNodeAllocationStrategy implements NodeAllocationSt private static final CommonConfig commonConfig = CommonDescriptor.getInstance().getConfig(); // manage wal folders - protected AtomicReference folderManager = new AtomicReference<>(); + protected FolderManager folderManager; protected AbstractNodeAllocationStrategy() { try { - folderManager.set( + folderManager = new FolderManager( - Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY)); + Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY); } catch (DiskSpaceInsufficientException e) { logger.error( "Fail to create wal node allocation strategy because all disks of wal folders are full.", @@ -56,18 +55,15 @@ protected AbstractNodeAllocationStrategy() { } } - protected IWALNode createWALNode(String identifier) { + protected synchronized IWALNode createWALNode(String identifier) { try { - // already in lock, so no need to synchronized - if (folderManager.get() == null) { - folderManager.set( + if (folderManager == null) { + folderManager = new FolderManager( - Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY)); + Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY); } - return folderManager - .get() - .getNextWithRetry( - folder -> new WALNode(identifier, folder + File.separator + identifier)); + return folderManager.getNextWithRetry( + folder -> new WALNode(identifier, folder + File.separator + identifier)); } catch (DiskSpaceInsufficientException e) { logger.error("Fail to create wal node because all disks of wal folders are full.", e); return WALFakeNode.getFailureInstance(e); @@ -79,15 +75,6 @@ protected IWALNode createWALNode(String identifier) { } } - protected IWALNode createWALNode(String identifier, String folder) { - try { - return new WALNode(identifier, folder); - } catch (IOException e) { - logger.error("Meet exception when creating wal node", e); - return WALFakeNode.getFailureInstance(e); - } - } - protected IWALNode createWALNode( String identifier, String folder, long startFileVersion, long startSearchIndex) { try { diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java index 523cc73f0f15..c9bfd6c497fb 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java @@ -38,6 +38,7 @@ import org.junit.Test; import java.io.File; +import java.io.IOException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -141,6 +142,79 @@ public void testRegisterWALNode() throws IllegalPathException { } } + @Test + public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, IOException { + // Create temporary directories for testing + File tempDir = new File(System.getProperty("java.io.tmpdir"), "iotdb_wal_reinit_test"); + tempDir.mkdirs(); + + String[] walDirs = + new String[] { + new File(tempDir, "wal_reinit_test1").getAbsolutePath(), + new File(tempDir, "wal_reinit_test2").getAbsolutePath(), + new File(tempDir, "wal_reinit_test3").getAbsolutePath() + }; + + String[] originalWalDirs = commonConfig.getWalDirs(); + commonConfig.setWalDirs(walDirs); + + try { + // Create strategy with valid directories first + FirstCreateStrategy strategy = new FirstCreateStrategy(); + + // Simulate folderManager becoming null (e.g., due to disk space issues) + // We'll use reflection to set folderManager to null to test re-initialization + try { + java.lang.reflect.Field folderManagerField = + AbstractNodeAllocationStrategy.class.getDeclaredField("folderManager"); + folderManagerField.setAccessible(true); + folderManagerField.set(strategy, null); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Failed to set folderManager to null for testing", e); + } + + // Now apply for WAL node, should successfully re-initialize folderManager + IWALNode walNode = strategy.applyForWALNode("test_reinit_identifier"); + assertNotNull("WAL node should be created after re-initialization", walNode); + + // Verify that WAL node was created successfully by logging data + walNode.log(1, getInsertRowNode()); + + // Verify that WAL files were created in at least one directory + boolean walFileCreated = false; + for (String walDir : walDirs) { + File walDirFile = new File(walDir); + if (walDirFile.exists()) { + File[] nodeDirs = walDirFile.listFiles(File::isDirectory); + if (nodeDirs != null && nodeDirs.length > 0) { + for (File nodeDir : nodeDirs) { + if (nodeDir.exists() && WALFileUtils.listAllWALFiles(nodeDir).length > 0) { + walFileCreated = true; + break; + } + } + } + } + if (walFileCreated) { + break; + } + } + assertTrue("WAL files should be created after re-initialization", walFileCreated); + + // Clean up + walNode.close(); + } finally { + // Clean up the test directories + for (String walDir : walDirs) { + EnvironmentUtils.cleanDir(walDir); + } + // Clean up temp directory + EnvironmentUtils.cleanDir(tempDir.getAbsolutePath()); + // Restore original WAL directories + commonConfig.setWalDirs(originalWalDirs); + } + } + private InsertRowNode getInsertRowNode() throws IllegalPathException { long time = 110L; TSDataType[] dataTypes = From 6c9046db1b70647fa1275740dda8dfec0b68d64a Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Sat, 13 Dec 2025 10:12:25 +0800 Subject: [PATCH 4/8] fix review by renaming Signed-off-by: OneSizeFitsQuorum --- .../wal/allocation/FirstCreateStrategyTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java index c9bfd6c497fb..d75dcbb72828 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java @@ -148,7 +148,7 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, File tempDir = new File(System.getProperty("java.io.tmpdir"), "iotdb_wal_reinit_test"); tempDir.mkdirs(); - String[] walDirs = + String[] testWalDirs = new String[] { new File(tempDir, "wal_reinit_test1").getAbsolutePath(), new File(tempDir, "wal_reinit_test2").getAbsolutePath(), @@ -156,7 +156,7 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, }; String[] originalWalDirs = commonConfig.getWalDirs(); - commonConfig.setWalDirs(walDirs); + commonConfig.setWalDirs(testWalDirs); try { // Create strategy with valid directories first @@ -182,7 +182,7 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, // Verify that WAL files were created in at least one directory boolean walFileCreated = false; - for (String walDir : walDirs) { + for (String walDir : testWalDirs) { File walDirFile = new File(walDir); if (walDirFile.exists()) { File[] nodeDirs = walDirFile.listFiles(File::isDirectory); @@ -205,7 +205,7 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, walNode.close(); } finally { // Clean up the test directories - for (String walDir : walDirs) { + for (String walDir : testWalDirs) { EnvironmentUtils.cleanDir(walDir); } // Clean up temp directory From 91ba86c6151a09f9005db11137a39a84be9afb99 Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Sat, 13 Dec 2025 10:27:42 +0800 Subject: [PATCH 5/8] enhance tests Signed-off-by: OneSizeFitsQuorum --- .../allocation/FirstCreateStrategyTest.java | 77 +++++++++++++++++-- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java index d75dcbb72828..2ebd945ae5d3 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java @@ -25,6 +25,8 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode; import org.apache.iotdb.db.storageengine.dataregion.wal.node.IWALNode; +import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALFakeNode; +import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALNode; import org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALFileUtils; import org.apache.iotdb.db.utils.EnvironmentUtils; import org.apache.iotdb.db.utils.constant.TestConstant; @@ -39,10 +41,13 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class FirstCreateStrategyTest { @@ -144,15 +149,14 @@ public void testRegisterWALNode() throws IllegalPathException { @Test public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, IOException { - // Create temporary directories for testing - File tempDir = new File(System.getProperty("java.io.tmpdir"), "iotdb_wal_reinit_test"); - tempDir.mkdirs(); + // Create unique temporary directory for testing + Path tempDir = Files.createTempDirectory("iotdb_wal_reinit_test_"); String[] testWalDirs = new String[] { - new File(tempDir, "wal_reinit_test1").getAbsolutePath(), - new File(tempDir, "wal_reinit_test2").getAbsolutePath(), - new File(tempDir, "wal_reinit_test3").getAbsolutePath() + tempDir.resolve("wal_reinit_test1").toString(), + tempDir.resolve("wal_reinit_test2").toString(), + tempDir.resolve("wal_reinit_test3").toString() }; String[] originalWalDirs = commonConfig.getWalDirs(); @@ -177,6 +181,11 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, IWALNode walNode = strategy.applyForWALNode("test_reinit_identifier"); assertNotNull("WAL node should be created after re-initialization", walNode); + // Verify that re-initialization actually occurred - should return WALNode, not WALFakeNode + assertTrue( + "Returned node should be WALNode instance after successful re-initialization", + walNode instanceof WALNode); + // Verify that WAL node was created successfully by logging data walNode.log(1, getInsertRowNode()); @@ -209,7 +218,61 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, EnvironmentUtils.cleanDir(walDir); } // Clean up temp directory - EnvironmentUtils.cleanDir(tempDir.getAbsolutePath()); + EnvironmentUtils.cleanDir(tempDir.toString()); + // Restore original WAL directories + commonConfig.setWalDirs(originalWalDirs); + } + } + + @Test + public void testReInitializeFailsWhenDiskStillFull() throws IllegalPathException, IOException { + // Create unique temporary directory for testing + Path tempDir = Files.createTempDirectory("iotdb_wal_reinit_fail_test_"); + + // Use non-existent directories that will cause re-initialization to fail + String[] nonExistentWalDirs = + new String[] { + tempDir.resolve("non_existent_dir1").toString(), + tempDir.resolve("non_existent_dir2").toString(), + tempDir.resolve("non_existent_dir3").toString() + }; + + String[] originalWalDirs = commonConfig.getWalDirs(); + commonConfig.setWalDirs(nonExistentWalDirs); + + try { + // Create strategy - this will fail to initialize folderManager + FirstCreateStrategy strategy = new FirstCreateStrategy(); + + // Verify that folderManager is null due to initialization failure + try { + java.lang.reflect.Field folderManagerField = + AbstractNodeAllocationStrategy.class.getDeclaredField("folderManager"); + folderManagerField.setAccessible(true); + Object folderManager = folderManagerField.get(strategy); + assertNull("folderManager should be null due to initialization failure", folderManager); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("Failed to access folderManager field", e); + } + + // Now apply for WAL node - re-initialization should also fail and return WALFakeNode + IWALNode walNode = strategy.applyForWALNode("test_reinit_fail_identifier"); + + // Verify that WALFakeNode is returned when re-initialization fails + assertNotNull("WAL node should be returned even when re-initialization fails", walNode); + assertTrue( + "Should return WALFakeNode when re-initialization fails", walNode instanceof WALFakeNode); + + // WALFakeNode should be the failure instance + WALFakeNode fakeNode = (WALFakeNode) walNode; + assertTrue( + "WALFakeNode should contain failure information", + fakeNode.toString().contains("DiskSpaceInsufficientException") + || fakeNode.toString().contains("Failed to create WAL node")); + + } finally { + // Clean up temp directory + EnvironmentUtils.cleanDir(tempDir.toString()); // Restore original WAL directories commonConfig.setWalDirs(originalWalDirs); } From 9f99286fe944f7639a68c11d186b5a83e52da7eb Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Sat, 13 Dec 2025 10:33:47 +0800 Subject: [PATCH 6/8] enhance tests Signed-off-by: OneSizeFitsQuorum --- .../allocation/FirstCreateStrategyTest.java | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java index 2ebd945ae5d3..f9a2fed45a8d 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java @@ -25,7 +25,6 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode; import org.apache.iotdb.db.storageengine.dataregion.wal.node.IWALNode; -import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALFakeNode; import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALNode; import org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALFileUtils; import org.apache.iotdb.db.utils.EnvironmentUtils; @@ -47,7 +46,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class FirstCreateStrategyTest { @@ -224,60 +222,6 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, } } - @Test - public void testReInitializeFailsWhenDiskStillFull() throws IllegalPathException, IOException { - // Create unique temporary directory for testing - Path tempDir = Files.createTempDirectory("iotdb_wal_reinit_fail_test_"); - - // Use non-existent directories that will cause re-initialization to fail - String[] nonExistentWalDirs = - new String[] { - tempDir.resolve("non_existent_dir1").toString(), - tempDir.resolve("non_existent_dir2").toString(), - tempDir.resolve("non_existent_dir3").toString() - }; - - String[] originalWalDirs = commonConfig.getWalDirs(); - commonConfig.setWalDirs(nonExistentWalDirs); - - try { - // Create strategy - this will fail to initialize folderManager - FirstCreateStrategy strategy = new FirstCreateStrategy(); - - // Verify that folderManager is null due to initialization failure - try { - java.lang.reflect.Field folderManagerField = - AbstractNodeAllocationStrategy.class.getDeclaredField("folderManager"); - folderManagerField.setAccessible(true); - Object folderManager = folderManagerField.get(strategy); - assertNull("folderManager should be null due to initialization failure", folderManager); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException("Failed to access folderManager field", e); - } - - // Now apply for WAL node - re-initialization should also fail and return WALFakeNode - IWALNode walNode = strategy.applyForWALNode("test_reinit_fail_identifier"); - - // Verify that WALFakeNode is returned when re-initialization fails - assertNotNull("WAL node should be returned even when re-initialization fails", walNode); - assertTrue( - "Should return WALFakeNode when re-initialization fails", walNode instanceof WALFakeNode); - - // WALFakeNode should be the failure instance - WALFakeNode fakeNode = (WALFakeNode) walNode; - assertTrue( - "WALFakeNode should contain failure information", - fakeNode.toString().contains("DiskSpaceInsufficientException") - || fakeNode.toString().contains("Failed to create WAL node")); - - } finally { - // Clean up temp directory - EnvironmentUtils.cleanDir(tempDir.toString()); - // Restore original WAL directories - commonConfig.setWalDirs(originalWalDirs); - } - } - private InsertRowNode getInsertRowNode() throws IllegalPathException { long time = 110L; TSDataType[] dataTypes = From 8b5c4c6e41c3055a9ead706af2741b79b4ff71f5 Mon Sep 17 00:00:00 2001 From: OneSizeFitsQuorum Date: Sat, 13 Dec 2025 10:49:48 +0800 Subject: [PATCH 7/8] add comments Signed-off-by: OneSizeFitsQuorum --- .../wal/allocation/AbstractNodeAllocationStrategy.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java index 9fdba1b14c41..a7780c74c1c1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java @@ -49,6 +49,8 @@ protected AbstractNodeAllocationStrategy() { new FolderManager( Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY); } catch (DiskSpaceInsufficientException e) { + // folderManager remains null when disk space is insufficient during initialization + // It will be lazily initialized later when disk space becomes available logger.error( "Fail to create wal node allocation strategy because all disks of wal folders are full.", e); @@ -57,6 +59,9 @@ protected AbstractNodeAllocationStrategy() { protected synchronized IWALNode createWALNode(String identifier) { try { + // Lazy initialization of folderManager: if it was null during constructor + // (due to insufficient disk space), try to initialize it now when disk space + // might have become available if (folderManager == null) { folderManager = new FolderManager( From f6b1b7df48504b758266ddedb44f66d1090c7b43 Mon Sep 17 00:00:00 2001 From: Potato Date: Sat, 13 Dec 2025 11:00:13 +0800 Subject: [PATCH 8/8] Update iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../dataregion/wal/allocation/FirstCreateStrategyTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java index f9a2fed45a8d..b60d83aef9c1 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/FirstCreateStrategyTest.java @@ -158,9 +158,9 @@ public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, }; String[] originalWalDirs = commonConfig.getWalDirs(); - commonConfig.setWalDirs(testWalDirs); try { + commonConfig.setWalDirs(testWalDirs); // Create strategy with valid directories first FirstCreateStrategy strategy = new FirstCreateStrategy();