Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,24 @@
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);
}
}

protected IWALNode createWALNode(String identifier) {
protected synchronized IWALNode createWALNode(String identifier) {

Check warning on line 60 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Abbreviation in name 'createWALNode' must contain no more than '2' consecutive capital letters.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZsVo7PAZyQppC4nKn18&open=AZsVo7PAZyQppC4nKn18&pullRequest=16869
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(
Arrays.asList(commonConfig.getWalDirs()), DirectoryStrategyType.SEQUENCE_STRATEGY);
}
return folderManager.getNextWithRetry(
folder -> new WALNode(identifier, folder + File.separator + identifier));
} catch (DiskSpaceInsufficientException e) {
Expand All @@ -70,15 +80,6 @@
}
}

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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
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.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;
Expand All @@ -38,6 +39,9 @@
import org.junit.Test;

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;
Expand Down Expand Up @@ -141,6 +145,83 @@ public void testRegisterWALNode() throws IllegalPathException {
}
}

@Test
public void testReInitializeAfterDiskSpaceCleaned() throws IllegalPathException, IOException {
// Create unique temporary directory for testing
Path tempDir = Files.createTempDirectory("iotdb_wal_reinit_test_");

String[] testWalDirs =
new String[] {
tempDir.resolve("wal_reinit_test1").toString(),
tempDir.resolve("wal_reinit_test2").toString(),
tempDir.resolve("wal_reinit_test3").toString()
};

String[] originalWalDirs = commonConfig.getWalDirs();

try {
commonConfig.setWalDirs(testWalDirs);
// 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 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());

// Verify that WAL files were created in at least one directory
boolean walFileCreated = false;
for (String walDir : testWalDirs) {
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 : testWalDirs) {
EnvironmentUtils.cleanDir(walDir);
}
// 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 =
Expand Down
Loading