Index: hbase-server/src/main/java/org/apache/hadoop/hbase/protobuf/ResponseConverter.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/protobuf/ResponseConverter.java (revision 1346770) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/protobuf/ResponseConverter.java (working copy) @@ -157,6 +157,23 @@ } /** + * Get a list of region opening state from a OpenRegionResponse + * + * @param proto the OpenRegionResponse + * @return the list of region opening state + */ + public static List getRegionOpeningStateList( + final OpenRegionResponse proto) { + if (proto == null) return null; + List regionOpeningStates = new ArrayList(); + for (int i = 0; i < proto.getOpeningStateCount(); i++) { + regionOpeningStates.add(RegionOpeningState.valueOf( + proto.getOpeningState(i).name())); + } + return regionOpeningStates; + } + + /** * Check if the region is closed from a CloseRegionResponse * * @param proto the CloseRegionResponse Index: hbase-server/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java (revision 1346770) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/protobuf/ProtobufUtil.java (working copy) @@ -78,6 +78,7 @@ import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileRequest; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetStoreFileResponse; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionRequest; +import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.OpenRegionResponse; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ReplicateWALEntryRequest; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.ServerInfo; import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.SplitRegionRequest; @@ -1304,17 +1305,18 @@ /** * A helper to open a list of regions using admin protocol. - * + * * @param admin * @param regions + * @return OpenRegionResponse * @throws IOException */ - public static void openRegion(final AdminProtocol admin, + public static OpenRegionResponse openRegion(final AdminProtocol admin, final List regions) throws IOException { OpenRegionRequest request = RequestConverter.buildOpenRegionRequest(regions); try { - admin.openRegion(null, request); + return admin.openRegion(null, request); } catch (ServiceException se) { throw getRemoteException(se); } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1346770) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy) @@ -1475,7 +1475,13 @@ getLong("hbase.regionserver.rpc.startup.waittime", 60000); while (!this.master.isStopped()) { try { - this.serverManager.sendRegionOpen(destination, regions); + List regionOpeningStateList = this.serverManager + .sendRegionOpen(destination, regions); + for (int i = 0; i < regionOpeningStateList.size(); i++) { + if (regionOpeningStateList.get(i) == RegionOpeningState.ALREADY_OPENED) { + alreadyOpendRegion(regions.get(i), destination); + } + } break; } catch (RemoteException e) { IOException decodedException = e.unwrapRemoteException(); @@ -1723,31 +1729,7 @@ RegionOpeningState regionOpenState = serverManager.sendRegionOpen(plan .getDestination(), state.getRegion(), versionOfOfflineNode); if (regionOpenState == RegionOpeningState.ALREADY_OPENED) { - // Remove region from in-memory transition and unassigned node from ZK - // While trying to enable the table the regions of the table were - // already enabled. - LOG.debug("ALREADY_OPENED region " + state.getRegion().getRegionNameAsString() + - " to " + plan.getDestination().toString()); - String encodedRegionName = state.getRegion() - .getEncodedName(); - try { - ZKAssign.deleteOfflineNode(master.getZooKeeper(), encodedRegionName); - } catch (KeeperException.NoNodeException e) { - if(LOG.isDebugEnabled()){ - LOG.debug("The unassigned node "+encodedRegionName+" doesnot exist."); - } - } catch (KeeperException e) { - master.abort( - "Error deleting OFFLINED node in ZK for transition ZK node (" - + encodedRegionName + ")", e); - } - // no lock concurrent ok -> sequentially consistent - this.regionsInTransition.remove(plan.getRegionInfo().getEncodedName()); - - synchronized (this.regions) { - this.regions.put(plan.getRegionInfo(), plan.getDestination()); - addToServers(plan.getDestination(), plan.getRegionInfo()); - } + alreadyOpendRegion(state.getRegion(), plan.getDestination()); } break; } catch (Throwable t) { @@ -1779,6 +1761,36 @@ } } + private void alreadyOpendRegion(HRegionInfo region, ServerName sn) { + + // Remove region from in-memory transition and unassigned node from ZK + // While trying to enable the table the regions of the table were + // already enabled. + LOG.debug("ALREADY_OPENED region " + region.getRegionNameAsString() + + " to " + sn); + String encodedRegionName = region.getEncodedName(); + try { + ZKAssign.deleteOfflineNode(master.getZooKeeper(), encodedRegionName); + } catch (KeeperException.NoNodeException e) { + if (LOG.isDebugEnabled()) { + LOG.debug("The unassigned node " + encodedRegionName + + " doesnot exist."); + } + } catch (KeeperException e) { + master.abort( + "Error deleting OFFLINED node in ZK for transition ZK node (" + + encodedRegionName + ")", e); + } + // no lock concurrent ok -> sequentially consistent + this.regionsInTransition.remove(region.getEncodedName()); + + synchronized (this.regions) { + this.regions.put(region, sn); + addToServers(sn, region); + } + + } + private boolean isDisabledorDisablingRegionInRIT(final HRegionInfo region) { String tableName = region.getTableNameAsString(); boolean disabled = this.zkTable.isDisabledTable(tableName); Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java (revision 1346770) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java (working copy) @@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.master.MasterServices; import org.apache.hadoop.hbase.master.ServerManager; import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.zookeeper.ZKAssign; import org.apache.zookeeper.KeeperException; /** @@ -305,6 +306,14 @@ + " because it has been opened in " + addressFromAM.getServerName()); } else { + if(rit != null){ + //clean zk node + try{ + ZKAssign.deleteNodeFailSilent(services.getZooKeeper(), e.getKey()); + }catch (KeeperException ke) { + throw new IOException(ke); + } + } toAssignRegions.add(e.getKey()); } } else if (rit != null && (rit.isSplitting() || rit.isSplit())) { Index: hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (revision 1346770) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (working copy) @@ -3369,8 +3369,18 @@ new HashMap(request.getRegionList().size()); for (RegionInfo regionInfo: request.getRegionList()) { HRegionInfo region = HRegionInfo.convert(regionInfo); - checkIfRegionInTransition(region, OPEN); - + try { + checkIfRegionInTransition(region, OPEN); + } catch (RegionAlreadyInTransitionException rite) { + if (request.getRegionList().size() > 1) { + // Opening regions for bulk assign, skip it and continue to open + // other regions + builder.addOpeningState(RegionOpeningState.OPENED); + continue; + } else { + throw rite; + } + } HRegion onlineRegion = getFromOnlineRegions(region.getEncodedName()); if (null != onlineRegion) { // See HBASE-5094. Cross check with META if still this RS is owning the Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java (revision 1346770) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java (working copy) @@ -511,16 +511,20 @@ *

* @param server server to open a region * @param regions regions to open + * @return a list of region opening state */ - public void sendRegionOpen(ServerName server, List regions) + public List sendRegionOpen(ServerName server, + List regions) throws IOException { AdminProtocol admin = getServerConnection(server); if (admin == null) { LOG.warn("Attempting to send OPEN RPC to server " + server.toString() + " failed because no RPC connection found to this server"); - return; + return null; } - ProtobufUtil.openRegion(admin, regions); + + OpenRegionResponse response = ProtobufUtil.openRegion(admin, regions); + return ResponseConverter.getRegionOpeningStateList(response); } /**