Skip to content

Commit

Permalink
RATIS-1871. Auto format RaftStorage when there is only one directory …
Browse files Browse the repository at this point in the history
…configured.
  • Loading branch information
szetszwo committed Aug 16, 2023
1 parent c8f4c46 commit 2eb7f86
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ static File chooseMin(Map<File, Integer> dirsPerVol) throws IOException {
* {@link StartupOption#RECOVER}:
* - When there are more than one existing directories, throw an exception.
* - When there is an existing directory, if it fails to initialize, throw an exception but not try a new directory.
* - When there is no existing directory, throw an exception.
* - When there is no existing directory, if only one directory is specified in the configuration, format it;
* otherwise, there are >1 directories specified, throw an exception.
*
* @param storageDirName the storage directory name
* @param option the startup option
Expand Down Expand Up @@ -125,7 +126,8 @@ RaftStorageImpl run() throws IOException {
if (option == StartupOption.FORMAT) {
return format();
} else if (option == StartupOption.RECOVER) {
return recover();
final RaftStorageImpl recovered = recover();
return recovered != null? recovered: format();
} else {
throw new IllegalArgumentException("Illegal option: " + option);
}
Expand Down Expand Up @@ -160,6 +162,10 @@ private RaftStorageImpl recover() throws IOException {
throw new IOException("Failed to " + option + ": More than one existing directories found "
+ existingSubs + " for " + storageDirName);
} else if (size == 0) {
if (dirsInConf.size() == 1) {
// fallback to FORMAT
return null;
}
throw new IOException("Failed to " + option + ": Storage directory not found for "
+ storageDirName + " from " + dirsInConf);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package org.apache.ratis.server.storage;

import org.apache.ratis.BaseTest;
import org.apache.ratis.conf.RaftProperties;
import org.apache.ratis.server.RaftServerConfigKeys;
import org.apache.ratis.util.FileUtils;
import org.apache.ratis.util.JavaUtils;
import org.junit.AfterClass;
Expand All @@ -39,7 +41,7 @@
/**
* Test cases to verify ServerState.
*/
public class TestStorageImplUtils {
public class TestStorageImplUtils extends BaseTest {

private static final Supplier<File> rootTestDir = JavaUtils.memoize(
() -> new File(BaseTest.getRootTestDir(),
Expand Down Expand Up @@ -128,4 +130,48 @@ public void testChooseStorageDirWithNoVolume() {
Assert.assertEquals(expectedErrMsg, ex.getMessage());
}
}

/**
* When there is only one directory specified in conf, auto format it.
*/
@Test
public void testAutoFormatSingleDirectory() throws Exception {
final File testDir = new File(rootTestDir.get(), UUID.randomUUID().toString());
FileUtils.createDirectories(testDir);

final RaftProperties properties = new RaftProperties();
RaftServerConfigKeys.setStorageDir(properties, Collections.singletonList(testDir));

final RaftStorageImpl storage = StorageImplUtils.initRaftStorage(
"group-1", RaftStorage.StartupOption.RECOVER, properties);
Assert.assertNotNull(storage);
storage.close();
}

/**
* When there are multiple directories specified in conf, do not auto format.
*/
@Test
public void testAutoFormatMultiDirectories() throws Exception {
final File testDir = new File(rootTestDir.get(), UUID.randomUUID().toString());
final List<File> directories = new ArrayList<>();
IntStream.range(0, 3).mapToObj((i) -> new File(testDir,
Integer.toString(i))).forEach((dir) -> {
try {
FileUtils.createDirectories(dir);
directories.add(dir);
} catch (IOException e) {
throw new RuntimeException(e);
}
});

final RaftProperties properties = new RaftProperties();
RaftServerConfigKeys.setStorageDir(properties, directories);

final Throwable ioe = testFailureCase("Do not auto format multi directories",
() -> StorageImplUtils.initRaftStorage(
"group-1", RaftStorage.StartupOption.RECOVER, properties),
IOException.class);
Assert.assertTrue(ioe.getMessage().contains("Failed to RECOVER: Storage directory not found"));
}
}

0 comments on commit 2eb7f86

Please sign in to comment.