From e710f6416ab060de931001329f77b79a14dabfc0 Mon Sep 17 00:00:00 2001 From: Mike Drob Date: Tue, 5 Dec 2017 14:25:37 -0600 Subject: [PATCH] HBASE-19289 Add flag to disable stream capability enforcement --- .../src/main/java/org/apache/hadoop/hbase/util/CommonFSUtils.java | 3 +++ .../hadoop/hbase/procedure2/store/wal/WALProcedureStore.java | 6 ++++-- .../org/apache/hadoop/hbase/procedure2/TestChildProcedures.java | 2 ++ .../org/apache/hadoop/hbase/procedure2/TestProcedureEvents.java | 2 ++ .../apache/hadoop/hbase/procedure2/TestProcedureExecution.java | 2 ++ .../org/apache/hadoop/hbase/procedure2/TestProcedureExecutor.java | 1 - .../org/apache/hadoop/hbase/procedure2/TestProcedureMetrics.java | 2 ++ .../org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java | 2 ++ .../org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java | 2 ++ .../apache/hadoop/hbase/procedure2/TestStateMachineProcedure.java | 2 ++ .../org/apache/hadoop/hbase/procedure2/TestYieldProcedures.java | 2 ++ .../hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java | 2 ++ .../org/apache/hadoop/hbase/io/asyncfs/AsyncFSOutputHelper.java | 8 +++++--- .../apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java | 3 ++- .../java/org/apache/hadoop/hbase/regionserver/TestHStore.java | 4 +++- 15 files changed, 35 insertions(+), 8 deletions(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CommonFSUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CommonFSUtils.java index bdf148eff1..e745bdb2ec 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CommonFSUtils.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CommonFSUtils.java @@ -62,6 +62,9 @@ public abstract class CommonFSUtils { /** Parameter name for HBase WAL directory */ public static final String HBASE_WAL_DIR = "hbase.wal.dir"; + /** Parameter to disable stream capability enforcement checks */ + public static final String UNSAFE_STREAM_CAPABILITY_ENFORCE = "hbase.unsafe.stream.capability.enforce"; + /** Full access permissions (starting point for a umask) */ public static final String FULL_RWX_PERMISSIONS = "777"; diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.java index f49833c77b..84cda6526f 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/store/wal/WALProcedureStore.java @@ -131,6 +131,7 @@ public class WALProcedureStore extends ProcedureStoreBase { private final FileSystem fs; private final Path walDir; private final Path walArchiveDir; + private final boolean enforceStreamCapability; private final AtomicReference syncException = new AtomicReference<>(); private final AtomicBoolean loading = new AtomicBoolean(true); @@ -205,6 +206,7 @@ public class WALProcedureStore extends ProcedureStoreBase { this.walDir = walDir; this.walArchiveDir = walArchiveDir; this.fs = walDir.getFileSystem(conf); + this.enforceStreamCapability = conf.getBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, true); // Create the log directory for the procedure store if (!fs.exists(walDir)) { @@ -1028,8 +1030,8 @@ public class WALProcedureStore extends ProcedureStoreBase { // ensure that we can provide the level of data safety we're configured // to provide. final String durability = useHsync ? "hsync" : "hflush"; - if (!(CommonFSUtils.hasCapability(newStream, durability))) { - throw new IllegalStateException("The procedure WAL relies on the ability to " + durability + + if (enforceStreamCapability && !(CommonFSUtils.hasCapability(newStream, durability))) { + throw new IllegalStateException("The procedure WAL relies on the ability to " + durability + " for proper operation during component failures, but the underlying filesystem does " + "not support doing so. Please check the config value of '" + USE_HSYNC_CONF_KEY + "' to set the desired level of robustness and ensure the config value of '" + diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java index 4c1611a6c5..2fdf313f49 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestChildProcedures.java @@ -28,6 +28,7 @@ import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.procedure2.store.ProcedureStore; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -54,6 +55,7 @@ public class TestChildProcedures { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureEvents.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureEvents.java index d2b2b7d54d..fdb21e3f8d 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureEvents.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureEvents.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.Procedu import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -55,6 +56,7 @@ public class TestProcedureEvents { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); Path testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); logDir = new Path(testDir, "proc-logs"); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java index ed6d512df7..2ebcc24b43 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecution.java @@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.procedure2.store.ProcedureStore; import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.ProcedureState; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.junit.After; import org.junit.Before; @@ -58,6 +59,7 @@ public class TestProcedureExecution { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecutor.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecutor.java index 289987be8b..da63f3f79a 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecutor.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureExecutor.java @@ -25,7 +25,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseCommonTestingUtility; -import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility; import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility.NoopProcedure; import org.apache.hadoop.hbase.procedure2.store.NoopProcedureStore; import org.apache.hadoop.hbase.testclassification.SmallTests; diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureMetrics.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureMetrics.java index 6246629ef9..36fc1760aa 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureMetrics.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureMetrics.java @@ -26,6 +26,7 @@ import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.procedure2.store.ProcedureStore; import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -60,6 +61,7 @@ public class TestProcedureMetrics { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java index 12a8012ef8..ba870c896c 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureNonce.java @@ -32,6 +32,7 @@ import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.apache.hadoop.hbase.util.NonceKey; import org.apache.hadoop.hbase.util.Threads; @@ -61,6 +62,7 @@ public class TestProcedureNonce { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); Path testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java index 06f8833a58..f3a5b63eef 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.shaded.com.google.protobuf.Int32Value; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.Threads; import org.junit.After; @@ -63,6 +64,7 @@ public class TestProcedureRecovery { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.java index cbe50f2c2d..a09c7e48f8 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestStateMachineProcedure.java @@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.procedure2.store.ProcedureStore; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -72,6 +73,7 @@ public class TestStateMachineProcedure { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestYieldProcedures.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestYieldProcedures.java index 017992cfea..61f582e2b4 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestYieldProcedures.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestYieldProcedures.java @@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.procedure2.store.ProcedureStore; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -60,6 +61,7 @@ public class TestYieldProcedures { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java index 98b1b7c9d6..9b523c34d2 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/store/wal/TestWALProcedureStore.java @@ -47,6 +47,7 @@ import org.apache.hadoop.hbase.procedure2.store.ProcedureStoreTracker; import org.apache.hadoop.hbase.shaded.com.google.protobuf.Int64Value; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.apache.hadoop.io.IOUtils; import org.junit.After; @@ -80,6 +81,7 @@ public class TestWALProcedureStore { @Before public void setUp() throws IOException { htu = new HBaseCommonTestingUtility(); + htu.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); testDir = htu.getDataTestDir(); fs = testDir.getFileSystem(htu.getConfiguration()); assertTrue(testDir.depth() > 1); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/asyncfs/AsyncFSOutputHelper.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/asyncfs/AsyncFSOutputHelper.java index 6a7e4fa0b3..6bf9fd99c3 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/asyncfs/AsyncFSOutputHelper.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/asyncfs/AsyncFSOutputHelper.java @@ -73,9 +73,11 @@ public final class AsyncFSOutputHelper { // After we create the stream but before we attempt to use it at all // ensure that we can provide the level of data safety we're configured // to provide. - if (!(CommonFSUtils.hasCapability(fsOut, "hflush") && - CommonFSUtils.hasCapability(fsOut, "hsync"))) { - throw new CommonFSUtils.StreamLacksCapabilityException("hflush and hsync"); + if (fs.getConf().getBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, true)) { + if (!(CommonFSUtils.hasCapability(fsOut, "hflush") && + CommonFSUtils.hasCapability(fsOut, "hsync"))) { + throw new CommonFSUtils.StreamLacksCapabilityException("hflush and hsync"); + } } final ExecutorService flushExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setDaemon(true) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java index d1e72f764c..0b52e394df 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/ProtobufLogWriter.java @@ -92,7 +92,8 @@ public class ProtobufLogWriter extends AbstractProtobufLogWriter this.output = fs.createNonRecursive(path, overwritable, bufferSize, replication, blockSize, null); // TODO Be sure to add a check for hsync if this branch includes HBASE-19024 - if (!(CommonFSUtils.hasCapability(output, "hflush"))) { + if (fs.getConf().getBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, true) && + !(CommonFSUtils.hasCapability(output, "hflush"))) { throw new StreamLacksCapabilityException("hflush"); } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHStore.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHStore.java index 39ed9dfa5b..92b56c7ea0 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHStore.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHStore.java @@ -97,6 +97,7 @@ import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.testclassification.MediumTests; import org.apache.hadoop.hbase.testclassification.RegionServerTests; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.CommonFSUtils; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.EnvironmentEdgeManagerTestHelper; import org.apache.hadoop.hbase.util.FSUtils; @@ -150,13 +151,14 @@ public class TestHStore { private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); private static final String DIR = TEST_UTIL.getDataTestDir("TestStore").toString(); - /** * Setup * @throws IOException */ @Before public void setUp() throws IOException { + TEST_UTIL.getConfiguration().setBoolean(CommonFSUtils.UNSAFE_STREAM_CAPABILITY_ENFORCE, false); + qualifiers.add(qf1); qualifiers.add(qf3); qualifiers.add(qf5); -- 2.15.0