You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by mb...@apache.org on 2015/04/27 23:02:09 UTC
[2/3] hbase git commit: HBASE-13394 Failed to recreate a table when
quota is enabled
HBASE-13394 Failed to recreate a table when quota is enabled
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/f8624125
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/f8624125
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/f8624125
Branch: refs/heads/branch-1
Commit: f862412592fc4654a827b7594098b3373a6bb1a2
Parents: 51177c4
Author: Matteo Bertozzi <ma...@cloudera.com>
Authored: Mon Apr 27 21:43:39 2015 +0100
Committer: Matteo Bertozzi <ma...@cloudera.com>
Committed: Mon Apr 27 21:49:58 2015 +0100
----------------------------------------------------------------------
.../org/apache/hadoop/hbase/master/HMaster.java | 3 +-
.../master/procedure/CreateTableProcedure.java | 5 ++
.../master/procedure/DeleteTableProcedure.java | 14 +----
.../master/procedure/ProcedureSyncWait.java | 12 ++++
.../hbase/namespace/TestNamespaceAuditor.java | 64 ++++++++++++++++++++
5 files changed, 83 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/f8624125/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index 530dcea..4886f59 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -1376,8 +1376,7 @@ public class HMaster extends HRegionServer implements MasterServices, Server {
HRegionInfo[] newRegions = ModifyRegionUtils.createHRegionInfos(hTableDescriptor, splitKeys);
checkInitialized();
sanityCheckTableDescriptor(hTableDescriptor);
- this.quotaManager.checkNamespaceTableAndRegionQuota(hTableDescriptor.getTableName(),
- newRegions.length);
+
if (cpHost != null) {
cpHost.preCreateTable(hTableDescriptor, newRegions);
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/f8624125/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java
index 2db04f3..360637f 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java
@@ -296,6 +296,11 @@ public class CreateTableProcedure
private void preCreate(final MasterProcedureEnv env)
throws IOException, InterruptedException {
+ if (!getTableName().isSystemTable()) {
+ ProcedureSyncWait.getMasterQuotaManager(env)
+ .checkNamespaceTableAndRegionQuota(getTableName(), newRegions.size());
+ }
+
final MasterCoprocessorHost cpHost = env.getMasterCoprocessorHost();
if (cpHost != null) {
final HRegionInfo[] regions = newRegions == null ? null :
http://git-wip-us.apache.org/repos/asf/hbase/blob/f8624125/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
index b61c850..2ba7b42 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/DeleteTableProcedure.java
@@ -53,7 +53,6 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProcedureProtos.DeleteTableState;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.procedure2.StateMachineProcedure;
-import org.apache.hadoop.hbase.quotas.MasterQuotaManager;
import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.security.UserGroupInformation;
@@ -406,17 +405,6 @@ public class DeleteTableProcedure
protected static void deleteTableStates(final MasterProcedureEnv env, final TableName tableName)
throws IOException {
- getMasterQuotaManager(env).removeTableFromNamespaceQuota(tableName);
- }
-
- private static MasterQuotaManager getMasterQuotaManager(final MasterProcedureEnv env)
- throws IOException {
- return ProcedureSyncWait.waitFor(env, "quota manager to be available",
- new ProcedureSyncWait.Predicate<MasterQuotaManager>() {
- @Override
- public MasterQuotaManager evaluate() throws IOException {
- return env.getMasterServices().getMasterQuotaManager();
- }
- });
+ ProcedureSyncWait.getMasterQuotaManager(env).removeTableFromNamespaceQuota(tableName);
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/f8624125/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
index a57fa59..1e94744 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/ProcedureSyncWait.java
@@ -42,6 +42,7 @@ import org.apache.hadoop.hbase.master.ServerManager;
import org.apache.hadoop.hbase.procedure2.Procedure;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.procedure2.ProcedureResult;
+import org.apache.hadoop.hbase.quotas.MasterQuotaManager;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.Threads;
import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
@@ -177,4 +178,15 @@ public final class ProcedureSyncWait {
});
}
}
+
+ protected static MasterQuotaManager getMasterQuotaManager(final MasterProcedureEnv env)
+ throws IOException {
+ return ProcedureSyncWait.waitFor(env, "quota manager to be available",
+ new ProcedureSyncWait.Predicate<MasterQuotaManager>() {
+ @Override
+ public MasterQuotaManager evaluate() throws IOException {
+ return env.getMasterServices().getMasterQuotaManager();
+ }
+ });
+ }
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/f8624125/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
index 1f0a827..8540dcf 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/namespace/TestNamespaceAuditor.java
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.Collections;
@@ -33,6 +34,7 @@ import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MiniHBaseCluster;
@@ -95,6 +97,7 @@ public class TestNamespaceAuditor {
Configuration conf = UTIL.getConfiguration();
conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, CustomObserver.class.getName());
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, MasterSyncObserver.class.getName());
+ conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 5);
conf.setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
conf.setClass("hbase.coprocessor.regionserver.classes", CPRegionServerObserver.class,
RegionServerObserver.class);
@@ -476,6 +479,58 @@ public class TestNamespaceAuditor {
htable.close();
}
+ /*
+ * Create a table and make sure that the table creation fails after adding this table entry into
+ * namespace quota cache. Now correct the failure and recreate the table with same name.
+ * HBASE-13394
+ */
+ @Test(timeout = 180000)
+ public void testRecreateTableWithSameNameAfterFirstTimeFailure() throws Exception {
+ String nsp1 = prefix + "_testRecreateTable";
+ NamespaceDescriptor nspDesc =
+ NamespaceDescriptor.create(nsp1)
+ .addConfiguration(TableNamespaceManager.KEY_MAX_REGIONS, "20")
+ .addConfiguration(TableNamespaceManager.KEY_MAX_TABLES, "1").build();
+ ADMIN.createNamespace(nspDesc);
+ final TableName tableOne = TableName.valueOf(nsp1 + TableName.NAMESPACE_DELIM + "table1");
+ byte[] columnFamily = Bytes.toBytes("info");
+ HTableDescriptor tableDescOne = new HTableDescriptor(tableOne);
+ tableDescOne.addFamily(new HColumnDescriptor(columnFamily));
+ MasterSyncObserver.throwExceptionInPreCreateTableHandler = true;
+ try {
+ try {
+ ADMIN.createTable(tableDescOne);
+ fail("Table " + tableOne.toString() + "creation should fail.");
+ } catch (Exception exp) {
+ LOG.error(exp);
+ }
+ assertFalse(ADMIN.tableExists(tableOne));
+
+ NamespaceTableAndRegionInfo nstate = getNamespaceState(nsp1);
+ assertEquals("First table creation failed in namespace so number of tables in namespace "
+ + "should be 0.", 0, nstate.getTables().size());
+
+ MasterSyncObserver.throwExceptionInPreCreateTableHandler = false;
+ try {
+ ADMIN.createTable(tableDescOne);
+ } catch (Exception e) {
+ fail("Table " + tableOne.toString() + "creation should succeed.");
+ LOG.error(e);
+ }
+ assertTrue(ADMIN.tableExists(tableOne));
+ nstate = getNamespaceState(nsp1);
+ assertEquals("First table was created successfully so table size in namespace should "
+ + "be one now.", 1, nstate.getTables().size());
+ } finally {
+ MasterSyncObserver.throwExceptionInPreCreateTableHandler = false;
+ if (ADMIN.tableExists(tableOne)) {
+ ADMIN.disableTable(tableOne);
+ deleteTable(tableOne);
+ }
+ ADMIN.deleteNamespace(nsp1);
+ }
+ }
+
private NamespaceTableAndRegionInfo getNamespaceState(String namespace) throws KeeperException,
IOException {
return getQuotaManager().getState(namespace);
@@ -575,6 +630,7 @@ public class TestNamespaceAuditor {
public static class MasterSyncObserver extends BaseMasterObserver {
volatile CountDownLatch tableDeletionLatch;
+ static boolean throwExceptionInPreCreateTableHandler;
@Override
public void preDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
@@ -587,6 +643,14 @@ public class TestNamespaceAuditor {
TableName tableName) throws IOException {
tableDeletionLatch.countDown();
}
+
+ @Override
+ public void preCreateTableHandler(ObserverContext<MasterCoprocessorEnvironment> ctx,
+ HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
+ if (throwExceptionInPreCreateTableHandler) {
+ throw new IOException("Throw exception as it is demanded.");
+ }
+ }
}
private void deleteTable(final TableName tableName) throws Exception {