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 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 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 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