diff --git a/hbase-server/pom.xml b/hbase-server/pom.xml
index c94f9776f63e..55f65436e699 100644
--- a/hbase-server/pom.xml
+++ b/hbase-server/pom.xml
@@ -308,6 +308,11 @@
junit-vintage-engine
test
+
+ org.awaitility
+ awaitility
+ test
+
org.mockito
mockito-core
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java
index 7fd7f6fa5c48..0cef601d5b56 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java
@@ -468,7 +468,7 @@ public static MasterRegion create(MasterRegionParams params) throws IOException
params.archivedWalSuffix(), params.rollPeriodMs(), params.flushSize());
walRoller.start();
- WALFactory walFactory = new WALFactory(conf, server.getServerName().toString());
+ WALFactory walFactory = new WALFactory(conf, server.getServerName().toString(), server);
Path tableDir = CommonFSUtils.getTableDir(rootDir, td.getTableName());
Path initializingFlag = new Path(tableDir, INITIALIZING_FLAG);
Path initializedFlag = new Path(tableDir, INITIALIZED_FLAG);
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
index cf91f744bf7b..4add5cadf766 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
@@ -2105,8 +2105,8 @@ private void setupWALAndReplication() throws IOException {
throw new RegionServerRunningException(
"Region server has already created directory at " + this.serverName.toString());
}
- // Always create wal directory as now we need this when master restarts to find out the live
- // region servers.
+ // Create wal directory here and we will never create it again in other places. This is
+ // important to make sure that our fencing way takes effect. See HBASE-29797 for more details.
if (!this.walFs.mkdirs(logDir)) {
throw new IOException("Can not create wal directory " + logDir);
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/AbstractFSWAL.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/AbstractFSWAL.java
index 76e292bd8572..efa151dd6f25 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/AbstractFSWAL.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/AbstractFSWAL.java
@@ -424,10 +424,8 @@ protected AbstractFSWAL(final FileSystem fs, final Abortable abortable, final Pa
this.conf = conf;
this.abortable = abortable;
- if (!fs.exists(walDir) && !fs.mkdirs(walDir)) {
- throw new IOException("Unable to mkdir " + walDir);
- }
-
+ // Here we only crate archive dir, without wal dir. This is to make sure that our fencing way
+ // takes effect. See HBASE-29797 for more details.
if (!fs.exists(this.walArchiveDir)) {
if (!fs.mkdirs(this.walArchiveDir)) {
throw new IOException("Unable to mkdir " + this.walArchiveDir);
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
index 11a6c1804296..cedeb46f4307 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.hbase.wal;
+import com.google.errorprone.annotations.RestrictedApi;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.List;
@@ -31,6 +32,7 @@
import org.apache.hadoop.hbase.regionserver.wal.ProtobufWALStreamReader;
import org.apache.hadoop.hbase.regionserver.wal.ProtobufWALTailingReader;
import org.apache.hadoop.hbase.util.CancelableProgressable;
+import org.apache.hadoop.hbase.util.CommonFSUtils;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.LeaseNotRecoveredException;
import org.apache.hadoop.hbase.wal.WALProvider.Writer;
@@ -203,8 +205,10 @@ WALProvider getProvider(String key, String defaultValue, String providerId) thro
return provider;
}
+ @RestrictedApi(explanation = "Should only be called in tests", link = "",
+ allowedOnPath = ".*/src/test/.*|.*/HBaseTestingUtility.java|.*/WALPerformanceEvaluation.java")
public WALFactory(Configuration conf, String factoryId) throws IOException {
- this(conf, factoryId, null);
+ this(conf, factoryId, null, true);
}
/**
@@ -213,6 +217,30 @@ public WALFactory(Configuration conf, String factoryId) throws IOException {
* @param abortable the server to abort
*/
public WALFactory(Configuration conf, String factoryId, Abortable abortable) throws IOException {
+ this(conf, factoryId, abortable, false);
+ }
+
+ private static void createWALDirectory(Configuration conf, String factoryId) throws IOException {
+ FileSystem walFs = CommonFSUtils.getWALFileSystem(conf);
+ Path walRootDir = CommonFSUtils.getWALRootDir(conf);
+ Path walDir = new Path(walRootDir, AbstractFSWALProvider.getWALDirectoryName(factoryId));
+ if (!walFs.exists(walDir) && !walFs.mkdirs(walDir)) {
+ throw new IOException("Can not create wal directory " + walDir);
+ }
+ }
+
+ /**
+ * @param conf must not be null, will keep a reference to read params in later
+ * reader/writer instances.
+ * @param factoryId a unique identifier for this factory. used i.e. by filesystem
+ * implementations to make a directory
+ * @param abortable the server associated with this WAL file
+ * @param createWalDirectory pass {@code true} for testing purpose, to create the wal directory
+ * automatically. In normal code path, we should create it in
+ * HRegionServer setup.
+ */
+ private WALFactory(Configuration conf, String factoryId, Abortable abortable,
+ boolean createWalDirectory) throws IOException {
// until we've moved reader/writer construction down into providers, this initialization must
// happen prior to provider initialization, in case they need to instantiate a reader/writer.
timeoutMillis = conf.getInt("hbase.hlog.open.timeout", 300000);
@@ -229,6 +257,10 @@ public WALFactory(Configuration conf, String factoryId, Abortable abortable) thr
this.abortable = abortable;
// end required early initialization
if (conf.getBoolean(WAL_ENABLED, true)) {
+ if (createWalDirectory) {
+ // for testing only
+ createWALDirectory(conf, factoryId);
+ }
provider = getProvider(WAL_PROVIDER, DEFAULT_WAL_PROVIDER, null);
} else {
// special handling of existing configuration behavior.
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
index 4ebfa3f6cfe2..84aa1cbd821a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
@@ -2626,8 +2626,9 @@ public static WAL createWal(final Configuration conf, final Path rootDir, final
// The WAL subsystem will use the default rootDir rather than the passed in rootDir
// unless I pass along via the conf.
Configuration confForWAL = new Configuration(conf);
- confForWAL.set(HConstants.HBASE_DIR, rootDir.toString());
- return new WALFactory(confForWAL, "hregion-" + RandomStringUtils.randomNumeric(8)).getWAL(hri);
+ CommonFSUtils.setRootDir(confForWAL, rootDir);
+ return new WALFactory(confForWAL, "hregion-" + RandomStringUtils.insecure().nextNumeric(8))
+ .getWAL(hri);
}
/**
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestWALFencing.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestWALFencing.java
new file mode 100644
index 000000000000..9341dcd5d9a8
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestWALFencing.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master;
+
+import static org.awaitility.Awaitility.await;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.Collections;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
+import org.apache.hadoop.hbase.regionserver.Region;
+import org.apache.hadoop.hbase.testclassification.MasterTests;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.util.RecoverLeaseFSUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Testcase for HBASE-29797, where the lazy initialized WALProvider may recreate the WAL directory
+ * and cause our fencing way loses efficacy.
+ */
+@Tag(MasterTests.TAG)
+@Tag(MediumTests.TAG)
+public class TestWALFencing {
+
+ private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+
+ @BeforeAll
+ public static void setUp() throws Exception {
+ UTIL.startMiniCluster(3);
+ UTIL.getAdmin().balancerSwitch(false, true);
+ }
+
+ @AfterAll
+ public static void tearDown() throws IOException {
+ UTIL.shutdownMiniCluster();
+ }
+
+ @Test
+ public void testMoveMeta() throws Exception {
+ HRegionServer metaRs = UTIL.getRSForFirstRegionInTable(TableName.META_TABLE_NAME);
+ HRegionServer otherRs = UTIL.getOtherRegionServer(metaRs);
+ // do fencing here, i.e, kill otherRs
+ Path splittingDir = UTIL.getMiniHBaseCluster().getMaster().getMasterWalManager()
+ .getLogDirs(Collections.singleton(otherRs.getServerName())).get(0);
+ for (FileStatus walFile : otherRs.getWALFileSystem().listStatus(splittingDir)) {
+ RecoverLeaseFSUtils.recoverFileLease(otherRs.getWALFileSystem(), walFile.getPath(),
+ otherRs.getConfiguration());
+ }
+ // move meta region to otherRs, which should fail and crash otherRs, and then master will try to
+ // assign meta region to another rs
+ RegionInfo metaRegionInfo = metaRs.getRegions().stream().map(Region::getRegionInfo)
+ .filter(RegionInfo::isMetaRegion).findAny().get();
+ UTIL.getAdmin().move(metaRegionInfo.getEncodedNameAsBytes(), otherRs.getServerName());
+ // make sure that meta region is not on otherRs
+ await().during(Duration.ofSeconds(5)).atMost(Duration.ofSeconds(6))
+ .until(() -> otherRs.getRegions(TableName.META_TABLE_NAME).isEmpty());
+ }
+}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestCompactionPolicy.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestCompactionPolicy.java
index 5d764df9eb90..a9d48e236087 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestCompactionPolicy.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestCompactionPolicy.java
@@ -99,6 +99,7 @@ protected void initialize() throws IOException {
htd.addFamily(hcd);
HRegionInfo info = new HRegionInfo(htd.getTableName(), null, null, false);
+ fs.mkdirs(new Path(basedir, logName));
hlog = new FSHLog(fs, basedir, logName, conf);
ChunkCreator.initialize(MemStoreLAB.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null,
MemStoreLAB.INDEX_CHUNK_SIZE_PERCENTAGE_DEFAULT);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFailedAppendAndSync.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFailedAppendAndSync.java
index 676151f3eb7a..a460aa49220b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFailedAppendAndSync.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestFailedAppendAndSync.java
@@ -194,6 +194,7 @@ public long getSyncedLength() {
// the test.
FileSystem fs = FileSystem.get(CONF);
Path rootDir = new Path(dir + getName());
+ fs.mkdirs(new Path(rootDir, getName()));
DodgyFSLog dodgyWAL = new DodgyFSLog(fs, services, rootDir, getName(), CONF);
dodgyWAL.init();
LogRoller logRoller = new LogRoller(services);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
index 1d53a7d652bd..68b6c4919a29 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java
@@ -368,8 +368,9 @@ protected void doSync(long txid, boolean forceSync) throws IOException {
}
FileSystem fs = FileSystem.get(CONF);
- Path rootDir = new Path(dir + "testMemstoreSnapshotSize");
- MyFaultyFSLog faultyLog = new MyFaultyFSLog(fs, rootDir, "testMemstoreSnapshotSize", CONF);
+ Path rootDir = new Path(dir + method);
+ fs.mkdirs(new Path(rootDir, method));
+ MyFaultyFSLog faultyLog = new MyFaultyFSLog(fs, rootDir, method, CONF);
region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, faultyLog,
COLUMN_FAMILY_BYTES);
@@ -412,10 +413,10 @@ private static WAL createWALCompatibleWithFaultyFileSystem(String callingMethod,
@Test
public void testMemstoreSizeAccountingWithFailedPostBatchMutate() throws IOException {
- String testName = "testMemstoreSizeAccountingWithFailedPostBatchMutate";
FileSystem fs = FileSystem.get(CONF);
- Path rootDir = new Path(dir + testName);
- FSHLog hLog = new FSHLog(fs, rootDir, testName, CONF);
+ Path rootDir = new Path(dir + method);
+ fs.mkdirs(new Path(rootDir, method));
+ FSHLog hLog = new FSHLog(fs, rootDir, method, CONF);
hLog.init();
HRegion region = initHRegion(tableName, null, null, CONF, false, Durability.SYNC_WAL, hLog,
COLUMN_FAMILY_BYTES);
@@ -1251,8 +1252,10 @@ public long getSyncedLength() {
};
}
}
- FailAppendFlushMarkerWAL wal = new FailAppendFlushMarkerWAL(FileSystem.get(walConf),
- CommonFSUtils.getRootDir(walConf), method, walConf);
+ FileSystem fs = FileSystem.get(walConf);
+ Path rootDir = CommonFSUtils.getRootDir(walConf);
+ fs.mkdirs(new Path(rootDir, method));
+ FailAppendFlushMarkerWAL wal = new FailAppendFlushMarkerWAL(fs, rootDir, method, walConf);
wal.init();
this.region = initHRegion(tableName, HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, CONF,
false, Durability.USE_DEFAULT, wal, family);
@@ -3353,8 +3356,9 @@ public void testScanner_DeleteOneFamilyNotAnother() throws IOException {
@Test
public void testDataInMemoryWithoutWAL() throws IOException {
FileSystem fs = FileSystem.get(CONF);
- Path rootDir = new Path(dir + "testDataInMemoryWithoutWAL");
- FSHLog hLog = new FSHLog(fs, rootDir, "testDataInMemoryWithoutWAL", CONF);
+ Path rootDir = new Path(dir + method);
+ fs.mkdirs(new Path(rootDir, method));
+ FSHLog hLog = new FSHLog(fs, rootDir, method, CONF);
hLog.init();
// This chunk creation is done throughout the code base. Do we want to move it into core?
// It is missing from this test. W/o it we NPE.
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestLogRoller.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestLogRoller.java
index 154b2a839b08..f1d0aa4c6fad 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestLogRoller.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestLogRoller.java
@@ -58,12 +58,13 @@ public class TestLogRoller {
private static FileSystem FS;
@Before
- public void setup() throws Exception {
+ public void setUp() throws Exception {
CONF = TEST_UTIL.getConfiguration();
CONF.setInt("hbase.regionserver.logroll.period", LOG_ROLL_PERIOD);
CONF.setInt(HConstants.THREAD_WAKE_FREQUENCY, 300);
ROOT_DIR = TEST_UTIL.getRandomDir();
FS = FileSystem.get(CONF);
+ FS.mkdirs(new Path(ROOT_DIR, LOG_DIR));
RegionServerServices services = Mockito.mock(RegionServerServices.class);
Mockito.when(services.getConfiguration()).thenReturn(CONF);
ROLLER = new LogRoller(services);
@@ -74,7 +75,7 @@ public void setup() throws Exception {
public void tearDown() throws Exception {
ROLLER.close();
FS.close();
- TEST_UTIL.shutdownMiniCluster();
+ TEST_UTIL.cleanupTestDir();
}
/**
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestWALLockup.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestWALLockup.java
index 7925fe0073f5..731781bfc1b2 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestWALLockup.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestWALLockup.java
@@ -216,6 +216,7 @@ public void testLockupWhenSyncInMiddleOfZigZagSetup() throws IOException {
// OK. Now I have my mocked up Server & RegionServerServices and dodgy WAL, go ahead with test.
FileSystem fs = FileSystem.get(CONF);
Path rootDir = new Path(dir + getName());
+ fs.mkdirs(new Path(rootDir, getName()));
DodgyFSLog dodgyWAL = new DodgyFSLog(fs, rootDir, getName(), CONF);
dodgyWAL.init();
Path originalWAL = dodgyWAL.getCurrentFileName();
@@ -394,6 +395,7 @@ public long getSyncedLength() {
// OK. Now I have my mocked up Server & RegionServerServices and dodgy WAL, go ahead with test.
FileSystem fs = FileSystem.get(CONF);
Path rootDir = new Path(dir + getName());
+ fs.mkdirs(new Path(rootDir, getName()));
final DodgyFSLog dodgyWAL = new DodgyFSLog(fs, rootDir, getName(), CONF);
dodgyWAL.init();
// I need a log roller running.
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestFSWAL.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestFSWAL.java
index 1f04e2718be5..ea1d6e6de0b0 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestFSWAL.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestFSWAL.java
@@ -120,6 +120,7 @@ public void setUp() throws Exception {
final Path hbaseWALDir = TEST_UTIL.createWALRootDir();
DIR = new Path(hbaseWALDir, currentTest.getMethodName());
assertNotEquals(hbaseDir, hbaseWALDir);
+ FS.mkdirs(DIR);
}
@BeforeClass
@@ -392,9 +393,8 @@ public void testFindMemStoresEligibleForFlush() throws Exception {
@Test(expected = IOException.class)
public void testFailedToCreateWALIfParentRenamed()
throws IOException, CommonFSUtils.StreamLacksCapabilityException {
- final String name = "testFailedToCreateWALIfParentRenamed";
- AbstractFSWAL> wal = newWAL(FS, CommonFSUtils.getWALRootDir(CONF), name,
- HConstants.HREGION_OLDLOGDIR_NAME, CONF, null, true, null, null);
+ AbstractFSWAL> wal = newWAL(FS, CommonFSUtils.getWALRootDir(CONF),
+ currentTest.getMethodName(), HConstants.HREGION_OLDLOGDIR_NAME, CONF, null, true, null, null);
long filenum = EnvironmentEdgeManager.currentTime();
Path path = wal.computeFilename(filenum);
wal.createWriterInstance(path);
@@ -535,6 +535,7 @@ public void testWriteEntryCanBeNull() throws IOException {
private AbstractFSWAL> createHoldingWAL(String testName, AtomicBoolean startHoldingForAppend,
CountDownLatch holdAppend) throws IOException {
+ FS.mkdirs(new Path(CommonFSUtils.getRootDir(CONF), testName));
AbstractFSWAL> wal = newWAL(FS, CommonFSUtils.getRootDir(CONF), testName,
HConstants.HREGION_OLDLOGDIR_NAME, CONF, null, true, null, null);
wal.init();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestWALReplay.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestWALReplay.java
index 2628f7bc35a5..f4070d1b5b2a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestWALReplay.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/AbstractTestWALReplay.java
@@ -1031,6 +1031,7 @@ private HTableDescriptor createBasic1FamilyHTD(final TableName tableName) {
}
private MockWAL createMockWAL() throws IOException {
+ fs.mkdirs(new Path(hbaseRootDir, logName));
MockWAL wal = new MockWAL(fs, hbaseRootDir, logName, conf);
wal.init();
// Set down maximum recovery so we dfsclient doesn't linger retrying something
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALDurability.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALDurability.java
index 8402617c44b5..3e4a58ce8406 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALDurability.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALDurability.java
@@ -57,7 +57,7 @@ public static void tearDownAfterClass() throws Exception {
}
@Override
- protected CustomAsyncFSWAL getWAL(FileSystem fs, Path root, String logDir, Configuration conf)
+ protected CustomAsyncFSWAL getWAL0(FileSystem fs, Path root, String logDir, Configuration conf)
throws IOException {
CustomAsyncFSWAL wal =
new CustomAsyncFSWAL(fs, root, logDir, conf, GROUP, NioSocketChannel.class);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALRollStuck.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALRollStuck.java
index 2ef80db0e223..91ca37a2827e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALRollStuck.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncFSWALRollStuck.java
@@ -162,6 +162,7 @@ public void logRollRequested(RollRequestReason reason) {
}
};
+ UTIL.getTestFileSystem().mkdirs(new Path(rootDir, "log"));
WAL = new AsyncFSWAL(UTIL.getTestFileSystem(), rootDir, "log", "oldlog", conf,
Arrays.asList(listener), true, null, null, EVENT_LOOP_GROUP, CHANNEL_CLASS);
WAL.init();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncWALReplay.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncWALReplay.java
index ec2fb58a481b..6ef56e426bf7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncWALReplay.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestAsyncWALReplay.java
@@ -69,7 +69,9 @@ public static void tearDownAfterClass() throws Exception {
@Override
protected WAL createWAL(Configuration c, Path hbaseRootDir, String logName) throws IOException {
- AsyncFSWAL asyncFSWAL = new AsyncFSWAL(FileSystem.get(c), hbaseRootDir, logName,
+ FileSystem fs = hbaseRootDir.getFileSystem(c);
+ fs.mkdirs(new Path(hbaseRootDir, logName));
+ AsyncFSWAL asyncFSWAL = new AsyncFSWAL(fs, hbaseRootDir, logName,
HConstants.HREGION_OLDLOGDIR_NAME, c, null, true, null, null, GROUP, CHANNEL_CLASS);
asyncFSWAL.init();
return asyncFSWAL;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLog.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLog.java
index 6f9ed7edcb2f..0196ab74991d 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLog.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLog.java
@@ -110,6 +110,7 @@ protected void atHeadOfRingBufferEventHandlerAppend() {
public void testSyncRunnerIndexOverflow() throws IOException, NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException {
final String name = this.name.getMethodName();
+ FS.mkdirs(new Path(CommonFSUtils.getRootDir(CONF), name));
FSHLog log = new FSHLog(FS, CommonFSUtils.getRootDir(CONF), name,
HConstants.HREGION_OLDLOGDIR_NAME, CONF, null, true, null, null);
log.init();
@@ -240,6 +241,7 @@ public void testUnflushedSeqIdTracking() throws IOException, InterruptedExceptio
final CountDownLatch flushFinished = new CountDownLatch(1);
final CountDownLatch putFinished = new CountDownLatch(1);
+ FS.mkdirs(new Path(CommonFSUtils.getRootDir(CONF), name));
try (FSHLog log = new FSHLog(FS, CommonFSUtils.getRootDir(CONF), name,
HConstants.HREGION_OLDLOGDIR_NAME, CONF, null, true, null, null)) {
log.init();
@@ -353,6 +355,7 @@ public void close() throws IOException {
}
final byte[] b = Bytes.toBytes("b");
String name = this.name.getMethodName();
+ FS.mkdirs(new Path(CommonFSUtils.getRootDir(CONF), name));
// Have a FSHLog writer implementation that fails during close
try (FSHLog log = new FSHLog(FS, CommonFSUtils.getRootDir(CONF), name,
HConstants.HREGION_OLDLOGDIR_NAME, CONF, null, true, null, null)) {
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLogDurability.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLogDurability.java
index 777b7b3f3d61..9b045650807f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLogDurability.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestFSHLogDurability.java
@@ -36,7 +36,7 @@ public class TestFSHLogDurability extends WALDurabilityTestBase {
HBaseClassTestRule.forClass(TestFSHLogDurability.class);
@Override
- protected CustomFSHLog getWAL(FileSystem fs, Path root, String logDir, Configuration conf)
+ protected CustomFSHLog getWAL0(FileSystem fs, Path root, String logDir, Configuration conf)
throws IOException {
CustomFSHLog wal = new CustomFSHLog(fs, root, logDir, conf);
wal.init();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestWALReplay.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestWALReplay.java
index 8adf15876a49..ef2932d4c42f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestWALReplay.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestWALReplay.java
@@ -47,7 +47,9 @@ public static void setUpBeforeClass() throws Exception {
@Override
protected WAL createWAL(Configuration c, Path hbaseRootDir, String logName) throws IOException {
- FSHLog wal = new FSHLog(FileSystem.get(c), hbaseRootDir, logName, c);
+ FileSystem fs = hbaseRootDir.getFileSystem(c);
+ fs.mkdirs(new Path(hbaseRootDir, logName));
+ FSHLog wal = new FSHLog(fs, hbaseRootDir, logName, c);
wal.init();
// Set down maximum recovery so we dfsclient doesn't linger retrying something
// long gone.
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/WALDurabilityTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/WALDurabilityTestBase.java
index 81ac0bfbfdb2..e731fabbea98 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/WALDurabilityTestBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/WALDurabilityTestBase.java
@@ -69,7 +69,13 @@ public void tearDown() throws IOException {
TEST_UTIL.cleanupTestDir();
}
- protected abstract T getWAL(FileSystem fs, Path root, String logDir, Configuration conf)
+ protected final T getWAL(FileSystem fs, Path root, String logDir, Configuration conf)
+ throws IOException {
+ fs.mkdirs(new Path(root, logDir));
+ return getWAL0(fs, root, logDir, conf);
+ }
+
+ protected abstract T getWAL0(FileSystem fs, Path root, String logDir, Configuration conf)
throws IOException;
protected abstract void resetSyncFlag(T wal);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALFactory.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALFactory.java
index 1afdc6e0fa7d..11c166746626 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALFactory.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALFactory.java
@@ -621,7 +621,7 @@ public void visitLogEntryBeforeWrite(RegionInfo info, WALKey logKey, WALEdit log
@Test
public void testWALProviders() throws IOException {
Configuration conf = new Configuration();
- WALFactory walFactory = new WALFactory(conf, this.currentServername.toString());
+ WALFactory walFactory = new WALFactory(conf, this.currentServername.toString(), null);
assertEquals(walFactory.getWALProvider().getClass(), walFactory.getMetaProvider().getClass());
}
@@ -629,7 +629,7 @@ public void testWALProviders() throws IOException {
public void testOnlySetWALProvider() throws IOException {
Configuration conf = new Configuration();
conf.set(WAL_PROVIDER, WALFactory.Providers.multiwal.name());
- WALFactory walFactory = new WALFactory(conf, this.currentServername.toString());
+ WALFactory walFactory = new WALFactory(conf, this.currentServername.toString(), null);
assertEquals(WALFactory.Providers.multiwal.clazz, walFactory.getWALProvider().getClass());
assertEquals(WALFactory.Providers.multiwal.clazz, walFactory.getMetaProvider().getClass());
@@ -639,7 +639,7 @@ public void testOnlySetWALProvider() throws IOException {
public void testOnlySetMetaWALProvider() throws IOException {
Configuration conf = new Configuration();
conf.set(META_WAL_PROVIDER, WALFactory.Providers.asyncfs.name());
- WALFactory walFactory = new WALFactory(conf, this.currentServername.toString());
+ WALFactory walFactory = new WALFactory(conf, this.currentServername.toString(), null);
assertEquals(WALFactory.Providers.defaultProvider.clazz,
walFactory.getWALProvider().getClass());
@@ -650,14 +650,15 @@ public void testOnlySetMetaWALProvider() throws IOException {
public void testDefaultProvider() throws IOException {
final Configuration conf = new Configuration();
// AsyncFSWal is the default, we should be able to request any WAL.
- final WALFactory normalWalFactory = new WALFactory(conf, this.currentServername.toString());
+ final WALFactory normalWalFactory =
+ new WALFactory(conf, this.currentServername.toString(), null);
Class extends WALProvider> fshLogProvider =
normalWalFactory.getProviderClass(WALFactory.WAL_PROVIDER, Providers.filesystem.name());
assertEquals(Providers.filesystem.clazz, fshLogProvider);
// Imagine a world where MultiWAL is the default
final WALFactory customizedWalFactory =
- new WALFactory(conf, this.currentServername.toString()) {
+ new WALFactory(conf, this.currentServername.toString(), null) {
@Override
Providers getDefaultProvider() {
return Providers.multiwal;
@@ -673,7 +674,7 @@ Providers getDefaultProvider() {
public void testCustomProvider() throws IOException {
final Configuration config = new Configuration();
config.set(WALFactory.WAL_PROVIDER, IOTestProvider.class.getName());
- final WALFactory walFactory = new WALFactory(config, this.currentServername.toString());
+ final WALFactory walFactory = new WALFactory(config, this.currentServername.toString(), null);
Class extends WALProvider> walProvider =
walFactory.getProviderClass(WALFactory.WAL_PROVIDER, Providers.filesystem.name());
assertEquals(IOTestProvider.class, walProvider);
@@ -685,7 +686,7 @@ public void testCustomProvider() throws IOException {
public void testCustomMetaProvider() throws IOException {
final Configuration config = new Configuration();
config.set(WALFactory.META_WAL_PROVIDER, IOTestProvider.class.getName());
- final WALFactory walFactory = new WALFactory(config, this.currentServername.toString());
+ final WALFactory walFactory = new WALFactory(config, this.currentServername.toString(), null);
Class extends WALProvider> walProvider =
walFactory.getProviderClass(WALFactory.WAL_PROVIDER, Providers.filesystem.name());
assertEquals(Providers.filesystem.clazz, walProvider);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALSplitToHFile.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALSplitToHFile.java
index 9bd4e32279e9..cac63289ed2e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALSplitToHFile.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/wal/TestWALSplitToHFile.java
@@ -171,12 +171,15 @@ private TableDescriptor createBasic3FamilyTD(final TableName tableName) throws I
}
private WAL createWAL(Configuration c, Path hbaseRootDir, String logName) throws IOException {
- FSHLog wal = new FSHLog(FileSystem.get(c), hbaseRootDir, logName, c);
+ FileSystem fs = hbaseRootDir.getFileSystem(c);
+ fs.mkdirs(new Path(hbaseRootDir, logName));
+ FSHLog wal = new FSHLog(fs, hbaseRootDir, logName, c);
wal.init();
return wal;
}
private WAL createWAL(FileSystem fs, Path hbaseRootDir, String logName) throws IOException {
+ fs.mkdirs(new Path(hbaseRootDir, logName));
FSHLog wal = new FSHLog(fs, hbaseRootDir, logName, this.conf);
wal.init();
return wal;
diff --git a/pom.xml b/pom.xml
index ea658b63e3fd..b5af54e2d39d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -598,6 +598,7 @@
9.4.14.0
5.13.4
5.13.4
+ 4.3.0
1.3
1.49.0
1.29.0-alpha
@@ -1397,6 +1398,12 @@
${junit.vintage.version}
test
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
org.hamcrest
hamcrest-core