You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2011/08/26 20:59:27 UTC
svn commit: r1162209 - in /hbase/trunk: ./
src/main/java/org/apache/hadoop/hbase/client/
src/main/java/org/apache/hadoop/hbase/executor/
src/main/java/org/apache/hadoop/hbase/ipc/
src/main/java/org/apache/hadoop/hbase/master/ src/main/java/org/apache/h...
Author: stack
Date: Fri Aug 26 18:59:26 2011
New Revision: 1162209
URL: http://svn.apache.org/viewvc?rev=1162209&view=rev
Log:
HBASE-3229 Table creation, though using async call to master, can actually run for a while and cause RPC timeout
Added:
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/CreateTableHandler.java
Modified:
hbase/trunk/CHANGES.txt
hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/ExecutorService.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java
hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java
hbase/trunk/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Fri Aug 26 18:59:26 2011
@@ -217,6 +217,8 @@ Release 0.91.0 - Unreleased
HTable(tablename) (Ramkrishna)
HBASE-4217 HRS.closeRegion should be able to close regions with only
the encoded name (ramkrishna.s.vasudevan)
+ HBASE-3229 HBASE-3229 Table creation, though using "async" call to master,
+ can actually run for a while and cause RPC timeout (Ming Ma)
IMPROVEMENTS
HBASE-3290 Max Compaction Size (Nicolas Spiegelberg via Stack)
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Fri Aug 26 18:59:26 2011
@@ -352,7 +352,8 @@ public class HBaseAdmin implements Abort
}
int numRegs = splitKeys == null ? 1 : splitKeys.length + 1;
int prevRegCount = 0;
- for (int tries = 0; tries < numRetries; ++tries) {
+ for (int tries = 0; tries < this.numRetries * this.retryLongerMultiplier;
+ ++tries) {
// Wait for new table to come on-line
final AtomicInteger actualRegCount = new AtomicInteger(0);
MetaScannerVisitor visitor = new MetaScannerVisitor() {
@@ -383,9 +384,9 @@ public class HBaseAdmin implements Abort
};
MetaScanner.metaScan(conf, visitor, desc.getName());
if (actualRegCount.get() != numRegs) {
- if (tries == numRetries - 1) {
- throw new RegionOfflineException("Only " + actualRegCount.get() +
- " of " + numRegs + " regions are online; retries exhausted.");
+ if (tries == this.numRetries * this.retryLongerMultiplier - 1) {
+ throw new RegionOfflineException("Only " + actualRegCount.get() +
+ " of " + numRegs + " regions are online; retries exhausted.");
}
try { // Sleep
Thread.sleep(getPauseTime(tries));
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java Fri Aug 26 18:59:26 2011
@@ -126,6 +126,7 @@ public abstract class EventHandler imple
C_M_ADD_FAMILY (44), // Client asking Master to add family to table
C_M_DELETE_FAMILY (45), // Client asking Master to delete family of table
C_M_MODIFY_FAMILY (46), // Client asking Master to modify family of table
+ C_M_CREATE_TABLE (47), // Client asking Master to create a table
// Updates from master to ZK. This is done by the master and there is
// nothing to process by either Master or RS
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/ExecutorService.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/ExecutorService.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/ExecutorService.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/executor/ExecutorService.java Fri Aug 26 18:59:26 2011
@@ -124,6 +124,7 @@ public class ExecutorService {
case C_M_DISABLE_TABLE:
case C_M_ENABLE_TABLE:
case C_M_MODIFY_TABLE:
+ case C_M_CREATE_TABLE:
return ExecutorType.MASTER_TABLE_OPERATIONS;
// RegionServer executor services
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java Fri Aug 26 18:59:26 2011
@@ -54,9 +54,9 @@ public interface HMasterInterface extend
// Admin tools would use these cmds
/**
- * Creates a new table. If splitKeys are specified, then the table will be
- * created with an initial set of multiple regions. If splitKeys is null,
- * the table will be created with a single region.
+ * Creates a new table asynchronously. If splitKeys are specified, then the
+ * table will be created with an initial set of multiple regions.
+ * If splitKeys is null, the table will be created with a single region.
* @param desc table descriptor
* @param splitKeys
* @throws IOException
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Fri Aug 26 18:59:26 2011
@@ -71,6 +71,7 @@ import org.apache.hadoop.hbase.master.ha
import org.apache.hadoop.hbase.master.handler.TableAddFamilyHandler;
import org.apache.hadoop.hbase.master.handler.TableDeleteFamilyHandler;
import org.apache.hadoop.hbase.master.handler.TableModifyFamilyHandler;
+import org.apache.hadoop.hbase.master.handler.CreateTableHandler;
import org.apache.hadoop.hbase.master.metrics.MasterMetrics;
import org.apache.hadoop.hbase.monitoring.MonitoredTask;
import org.apache.hadoop.hbase.monitoring.TaskMonitor;
@@ -914,14 +915,8 @@ implements HMasterInterface, HMasterRegi
}
}
- public void createTable(HTableDescriptor desc, byte [][] splitKeys)
- throws IOException {
- createTable(desc, splitKeys, false);
- }
-
public void createTable(HTableDescriptor hTableDescriptor,
- byte [][] splitKeys,
- boolean sync)
+ byte [][] splitKeys)
throws IOException {
if (!isMasterRunning()) {
throw new MasterNotRunningException();
@@ -930,118 +925,39 @@ implements HMasterInterface, HMasterRegi
cpHost.preCreateTable(hTableDescriptor, splitKeys);
}
HRegionInfo [] newRegions = getHRegionInfos(hTableDescriptor, splitKeys);
- int timeout = conf.getInt("hbase.client.catalog.timeout", 10000);
- // Need META availability to create a table
- try {
- if(catalogTracker.waitForMeta(timeout) == null) {
- throw new NotAllMetaRegionsOnlineException();
- }
- } catch (InterruptedException e) {
- LOG.warn("Interrupted waiting for meta availability", e);
- throw new IOException(e);
- }
- createTable(hTableDescriptor ,newRegions, sync);
- }
-
- private HRegionInfo[] getHRegionInfos(HTableDescriptor hTableDescriptor,
- byte[][] splitKeys) {
- HRegionInfo[] hRegionInfos = null;
- if (splitKeys == null || splitKeys.length == 0) {
- hRegionInfos = new HRegionInfo[]{
- new HRegionInfo(hTableDescriptor.getName(), null, null)};
- } else {
- int numRegions = splitKeys.length + 1;
- hRegionInfos = new HRegionInfo[numRegions];
- byte[] startKey = null;
- byte[] endKey = null;
- for (int i = 0; i < numRegions; i++) {
- endKey = (i == splitKeys.length) ? null : splitKeys[i];
- hRegionInfos[i] =
- new HRegionInfo(hTableDescriptor.getName(), startKey, endKey);
- startKey = endKey;
- }
- }
- return hRegionInfos;
-}
- private synchronized void createTable(final HTableDescriptor hTableDescriptor,
- final HRegionInfo [] newRegions,
- final boolean sync)
- throws IOException {
- String tableName = newRegions[0].getTableNameAsString();
- if (MetaReader.tableExists(catalogTracker, tableName)) {
- throw new TableExistsException(tableName);
- }
- // TODO: Currently we make the table descriptor and as side-effect the
- // tableDir is created. Should we change below method to be createTable
- // where we create table in tmp dir with its table descriptor file and then
- // do rename to move it into place?
- FSUtils.createTableDescriptor(hTableDescriptor, conf);
+ this.executorService.submit(new CreateTableHandler(this,
+ this.fileSystemManager, this.serverManager, hTableDescriptor, conf,
+ newRegions, catalogTracker, assignmentManager));
- // 1. Set table enabling flag up in zk.
- try {
- assignmentManager.getZKTable().setEnabledTable(tableName);
- } catch (KeeperException e) {
- throw new IOException("Unable to ensure that the table will be" +
- " enabled because of a ZooKeeper issue", e);
- }
-
- List<HRegionInfo> regionInfos = new ArrayList<HRegionInfo>();
- final int batchSize = this.conf.getInt("hbase.master.createtable.batchsize", 100);
- HLog hlog = null;
- for (int regionIdx = 0; regionIdx < newRegions.length; regionIdx++) {
- HRegionInfo newRegion = newRegions[regionIdx];
- // 2. Create HRegion
- HRegion region = HRegion.createHRegion(newRegion,
- fileSystemManager.getRootDir(), conf, hTableDescriptor, hlog);
- if (hlog == null) {
- hlog = region.getLog();
- }
-
- regionInfos.add(region.getRegionInfo());
- if (regionIdx % batchSize == 0) {
- // 3. Insert into META
- MetaEditor.addRegionsToMeta(catalogTracker, regionInfos);
- regionInfos.clear();
- }
-
- // 4. Close the new region to flush to disk. Close log file too.
- region.close();
- }
- hlog.closeAndDelete();
- if (regionInfos.size() > 0) {
- MetaEditor.addRegionsToMeta(catalogTracker, regionInfos);
- }
-
- // 5. Trigger immediate assignment of the regions in round-robin fashion
- List<ServerName> servers = serverManager.getOnlineServersList();
- try {
- this.assignmentManager.assignUserRegions(Arrays.asList(newRegions), servers);
- } catch (InterruptedException ie) {
- LOG.error("Caught " + ie + " during round-robin assignment");
- throw new IOException(ie);
+ if (cpHost != null) {
+ // TODO, remove sync parameter from postCreateTable method
+ cpHost.postCreateTable(newRegions, false);
}
+ }
- // 6. If sync, wait for assignment of regions
- if (sync) {
- LOG.debug("Waiting for " + newRegions.length + " region(s) to be assigned");
- for (HRegionInfo regionInfo : newRegions) {
- try {
- this.assignmentManager.waitForAssignment(regionInfo);
- } catch (InterruptedException e) {
- LOG.info("Interrupted waiting for region to be assigned during " +
- "create table call", e);
- Thread.currentThread().interrupt();
- return;
- }
+ private HRegionInfo[] getHRegionInfos(HTableDescriptor hTableDescriptor,
+ byte[][] splitKeys) {
+ HRegionInfo[] hRegionInfos = null;
+ if (splitKeys == null || splitKeys.length == 0) {
+ hRegionInfos = new HRegionInfo[]{
+ new HRegionInfo(hTableDescriptor.getName(), null, null)};
+ } else {
+ int numRegions = splitKeys.length + 1;
+ hRegionInfos = new HRegionInfo[numRegions];
+ byte[] startKey = null;
+ byte[] endKey = null;
+ for (int i = 0; i < numRegions; i++) {
+ endKey = (i == splitKeys.length) ? null : splitKeys[i];
+ hRegionInfos[i] =
+ new HRegionInfo(hTableDescriptor.getName(), startKey, endKey);
+ startKey = endKey;
}
}
-
- if (cpHost != null) {
- cpHost.postCreateTable(newRegions, sync);
- }
+ return hRegionInfos;
}
+
private static boolean isCatalogTable(final byte [] tableName) {
return Bytes.equals(tableName, HConstants.ROOT_TABLE_NAME) ||
Bytes.equals(tableName, HConstants.META_TABLE_NAME);
Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/CreateTableHandler.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/CreateTableHandler.java?rev=1162209&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/CreateTableHandler.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/CreateTableHandler.java Fri Aug 26 18:59:26 2011
@@ -0,0 +1,190 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * 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.handler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.Server;
+import org.apache.hadoop.hbase.catalog.CatalogTracker;
+import org.apache.hadoop.hbase.catalog.MetaReader;
+import org.apache.hadoop.hbase.executor.EventHandler;
+import org.apache.hadoop.hbase.master.AssignmentManager;
+import org.apache.hadoop.hbase.master.ServerManager;
+import org.apache.hadoop.hbase.master.MasterFileSystem;
+import org.apache.zookeeper.KeeperException;
+import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
+import org.apache.hadoop.hbase.TableExistsException;
+import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.hadoop.hbase.regionserver.wal.HLog;
+import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.catalog.MetaEditor;
+import org.apache.hadoop.hbase.ServerName;
+
+/**
+ * Handler to create a table.
+ */
+public class CreateTableHandler extends EventHandler {
+ private static final Log LOG = LogFactory.getLog(CreateTableHandler.class);
+ private MasterFileSystem fileSystemManager;
+ private final HTableDescriptor hTableDescriptor;
+ private Configuration conf;
+ private final AssignmentManager assignmentManager;
+ private final CatalogTracker catalogTracker;
+ private final ServerManager serverManager;
+ private final HRegionInfo [] newRegions;
+
+ public CreateTableHandler(Server server, MasterFileSystem fileSystemManager,
+ ServerManager serverManager, HTableDescriptor hTableDescriptor,
+ Configuration conf, HRegionInfo [] newRegions,
+ CatalogTracker catalogTracker, AssignmentManager assignmentManager)
+ throws NotAllMetaRegionsOnlineException, TableExistsException,
+ IOException {
+ super(server, EventType.C_M_CREATE_TABLE);
+
+ this.fileSystemManager = fileSystemManager;
+ this.serverManager = serverManager;
+ this.hTableDescriptor = hTableDescriptor;
+ this.conf = conf;
+ this.newRegions = newRegions;
+ this.catalogTracker = catalogTracker;
+ this.assignmentManager = assignmentManager;
+
+ int timeout = conf.getInt("hbase.client.catalog.timeout", 10000);
+ // Need META availability to create a table
+ try {
+ if(catalogTracker.waitForMeta(timeout) == null) {
+ throw new NotAllMetaRegionsOnlineException();
+ }
+ } catch (InterruptedException e) {
+ LOG.warn("Interrupted waiting for meta availability", e);
+ throw new IOException(e);
+ }
+
+ String tableName = this.hTableDescriptor.getNameAsString();
+ if (MetaReader.tableExists(catalogTracker, tableName)) {
+ throw new TableExistsException(tableName);
+ }
+
+ // If we have multiple client threads trying to create the table at the
+ // same time, given the async nature of the operation, the table
+ // could be in a state where .META. table hasn't been updated yet in
+ // the process() function.
+ // Use enabling state to tell if there is already a request for the same
+ // table in progress. This will introduce a new zookeeper call. Given
+ // createTable isn't a frequent operation, that should be ok.
+ try {
+ if (!this.assignmentManager.getZKTable().checkAndSetEnablingTable(
+ tableName))
+ throw new TableExistsException(tableName);
+ } catch (KeeperException e) {
+ throw new IOException("Unable to ensure that the table will be" +
+ " enabling because of a ZooKeeper issue", e);
+ }
+ }
+
+
+ @Override
+ public String toString() {
+ String name = "UnknownServerName";
+ if(server != null && server.getServerName() != null) {
+ name = server.getServerName().toString();
+ }
+ return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" +
+ this.hTableDescriptor.getNameAsString();
+ }
+
+ @Override
+ public void process() {
+ String tableName = this.hTableDescriptor.getNameAsString();
+ try {
+ LOG.info("Attemping to create the table " + tableName);
+ handleCreateTable();
+ } catch (IOException e) {
+ LOG.error("Error trying to create the table " + tableName, e);
+ } catch (KeeperException e) {
+ LOG.error("Error trying to create the table " + tableName, e);
+ }
+ }
+
+ private void handleCreateTable() throws IOException, KeeperException {
+
+ // TODO: Currently we make the table descriptor and as side-effect the
+ // tableDir is created. Should we change below method to be createTable
+ // where we create table in tmp dir with its table descriptor file and then
+ // do rename to move it into place?
+ FSUtils.createTableDescriptor(this.hTableDescriptor, this.conf);
+
+ List<HRegionInfo> regionInfos = new ArrayList<HRegionInfo>();
+ final int batchSize =
+ this.conf.getInt("hbase.master.createtable.batchsize", 100);
+ HLog hlog = null;
+ for (int regionIdx = 0; regionIdx < this.newRegions.length; regionIdx++) {
+ HRegionInfo newRegion = this.newRegions[regionIdx];
+ // 1. Create HRegion
+ HRegion region = HRegion.createHRegion(newRegion,
+ this.fileSystemManager.getRootDir(), this.conf,
+ this.hTableDescriptor, hlog);
+ if (hlog == null) {
+ hlog = region.getLog();
+ }
+
+ regionInfos.add(region.getRegionInfo());
+ if (regionIdx % batchSize == 0) {
+ // 2. Insert into META
+ MetaEditor.addRegionsToMeta(this.catalogTracker, regionInfos);
+ regionInfos.clear();
+ }
+
+ // 3. Close the new region to flush to disk. Close log file too.
+ region.close();
+ }
+ hlog.closeAndDelete();
+ if (regionInfos.size() > 0) {
+ MetaEditor.addRegionsToMeta(this.catalogTracker, regionInfos);
+ }
+
+ // 4. Trigger immediate assignment of the regions in round-robin fashion
+ List<ServerName> servers = serverManager.getOnlineServersList();
+ try {
+ this.assignmentManager.assignUserRegions(Arrays.asList(newRegions),
+ servers);
+ } catch (InterruptedException ie) {
+ LOG.error("Caught " + ie + " during round-robin assignment");
+ throw new IOException(ie);
+ }
+
+ // 5. Set table enabled flag up in zk.
+ try {
+ assignmentManager.getZKTable().
+ setEnabledTable(this.hTableDescriptor.getNameAsString());
+ } catch (KeeperException e) {
+ throw new IOException("Unable to ensure that the table will be" +
+ " enabled because of a ZooKeeper issue", e);
+ }
+ }
+}
\ No newline at end of file
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java Fri Aug 26 18:59:26 2011
@@ -1,5 +1,5 @@
/**
- * Copyright 2010 The Apache Software Foundation
+ * Copyright 2011 The Apache Software Foundation
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -66,9 +66,10 @@ public class EnableTableHandler extends
if(server != null && server.getServerName() != null) {
name = server.getServerName().toString();
}
- return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" + tableNameStr;
+ return getClass().getSimpleName() + "-" + name + "-" + getSeqid() + "-" +
+ tableNameStr;
}
-
+
@Override
public void process() {
try {
@@ -119,7 +120,7 @@ public class EnableTableHandler extends
break;
}
}
- // Flip the table to disabled.
+ // Flip the table to enabled.
if (done) this.assignmentManager.getZKTable().setEnabledTable(this.tableNameStr);
LOG.info("Enabled table is done=" + done);
}
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKTable.java Fri Aug 26 18:59:26 2011
@@ -164,13 +164,31 @@ public class ZKTable {
throws KeeperException {
synchronized (this.cache) {
if (!isDisabledOrEnablingTable(tableName)) {
- LOG.warn("Moving table " + tableName + " state to disabling but was " +
- "not first in enabled state: " + this.cache.get(tableName));
+ LOG.warn("Moving table " + tableName + " state to enabling but was " +
+ "not first in disabled state: " + this.cache.get(tableName));
}
setTableState(tableName, TableState.ENABLING);
}
}
+ /**
+ * Sets the specified table as ENABLING in zookeeper atomically
+ * If the table is already in ENABLING state, no operation is performed
+ * @param tableName
+ * @return if the operation succeeds or not
+ * @throws KeeperException unexpected zookeeper exception
+ */
+ public boolean checkAndSetEnablingTable(final String tableName)
+ throws KeeperException {
+ synchronized (this.cache) {
+ if (isEnablingTable(tableName)) {
+ return false;
+ }
+ setTableState(tableName, TableState.ENABLING);
+ return true;
+ }
+ }
+
private void setTableState(final String tableName, final TableState state)
throws KeeperException {
String znode = ZKUtil.joinZNode(this.watcher.tableZNode, tableName);
Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java?rev=1162209&r1=1162208&r2=1162209&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java Fri Aug 26 18:59:26 2011
@@ -843,6 +843,27 @@ public class TestAdmin {
new HTable(TEST_UTIL.getConfiguration(), name);
}
+ /***
+ * HMaster.createTable used to be kind of synchronous call
+ * Thus creating of table with lots of regions can cause RPC timeout
+ * After the fix to make createTable truly async, RPC timeout shouldn't be an
+ * issue anymore
+ * @throws Exception
+ */
+ @Test
+ public void testCreateTableRPCTimeOut() throws Exception {
+ String name = "testCreateTableRPCTimeOut";
+ TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
+
+ int expectedRegions = 100;
+ // Use 80 bit numbers to make sure we aren't limited
+ byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
+ byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
+ HBaseAdmin hbaseadmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
+ hbaseadmin.createTable(new HTableDescriptor(name), startKey, endKey,
+ expectedRegions);
+ }
+
/**
* Test read only tables
* @throws Exception