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 1550346) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy) @@ -3488,4 +3488,11 @@ // remove the region plan as well just in case. clearRegionPlan(regionInfo); } + + /** + * @return Instance of load balancer + */ + public LoadBalancer getBalancer() { + return this.balancer; + } } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java (revision 1550346) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/balancer/BaseLoadBalancer.java (working copy) @@ -559,7 +559,9 @@ } else { // multiple new servers in the cluster on this same host int size = localServers.size(); - ServerName target = localServers.get(RANDOM.nextInt(size)); + ServerName target = + localServers.contains(oldServerName) ? oldServerName : localServers.get(RANDOM + .nextInt(size)); assignments.get(target).add(region); numRetainedAssigments++; } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java (revision 1550346) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/GeneralBulkAssigner.java (working copy) @@ -53,7 +53,7 @@ final AssignmentManager assignmentManager; final boolean waitTillAllAssigned; - GeneralBulkAssigner(final Server server, + public GeneralBulkAssigner(final Server server, final Map> bulkPlan, final AssignmentManager am, final boolean waitTillAllAssigned) { super(server); Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java (revision 1550346) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/EnableTableHandler.java (working copy) @@ -19,8 +19,9 @@ package org.apache.hadoop.hbase.master.handler; import java.io.IOException; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutorService; import org.apache.commons.logging.Log; @@ -38,9 +39,9 @@ import org.apache.hadoop.hbase.executor.EventType; import org.apache.hadoop.hbase.master.AssignmentManager; import org.apache.hadoop.hbase.master.BulkAssigner; +import org.apache.hadoop.hbase.master.GeneralBulkAssigner; import org.apache.hadoop.hbase.master.HMaster; import org.apache.hadoop.hbase.master.MasterCoprocessorHost; -import org.apache.hadoop.hbase.master.RegionPlan; import org.apache.hadoop.hbase.master.RegionStates; import org.apache.hadoop.hbase.master.ServerManager; import org.apache.hadoop.hbase.master.TableLockManager; @@ -173,22 +174,29 @@ // Set table enabling flag up in zk. this.assignmentManager.getZKTable().setEnablingTable(this.tableName); boolean done = false; + ServerManager serverManager = ((HMaster)this.server).getServerManager(); // Get the regions of this table. We're done when all listed // tables are onlined. List> tableRegionsAndLocations = MetaReader .getTableRegionsAndLocations(this.catalogTracker, tableName, true); int countOfRegionsInTable = tableRegionsAndLocations.size(); - List regions = regionsToAssignWithServerName(tableRegionsAndLocations); - int regionsCount = regions.size(); + Map regionsToAssign = + regionsToAssignWithServerName(tableRegionsAndLocations); + int regionsCount = regionsToAssign.size(); if (regionsCount == 0) { done = true; } LOG.info("Table '" + this.tableName + "' has " + countOfRegionsInTable + " regions, of which " + regionsCount + " are offline."); - BulkEnabler bd = new BulkEnabler(this.server, regions, countOfRegionsInTable, - true); + List onlineServers = serverManager.createDestinationServersList(); + Map> bulkPlan = + this.assignmentManager.getBalancer().retainAssignment(regionsToAssign, onlineServers); + LOG.info("Bulk assigning " + regionsCount + " region(s) across " + bulkPlan.size() + + " server(s), retainAssignment=true"); + + BulkAssigner ba = new GeneralBulkAssigner(this.server, bulkPlan, this.assignmentManager, true); try { - if (bd.bulkAssign()) { + if (ba.bulkAssign()) { done = true; } } catch (InterruptedException e) { @@ -214,19 +222,16 @@ * @return List of regions neither in transition nor assigned. * @throws IOException */ - private List regionsToAssignWithServerName( + private Map regionsToAssignWithServerName( final List> regionsInMeta) throws IOException { - ServerManager serverManager = ((HMaster) this.server).getServerManager(); - List regions = new ArrayList(); + Map regionsToAssign = + new HashMap(regionsInMeta.size()); RegionStates regionStates = this.assignmentManager.getRegionStates(); for (Pair regionLocation : regionsInMeta) { HRegionInfo hri = regionLocation.getFirst(); ServerName sn = regionLocation.getSecond(); if (regionStates.isRegionOffline(hri)) { - if (sn != null && serverManager.isServerOnline(sn)) { - this.assignmentManager.addPlan(hri.getEncodedName(), new RegionPlan(hri, null, sn)); - } - regions.add(hri); + regionsToAssign.put(hri, sn); } else { if (LOG.isDebugEnabled()) { LOG.debug("Skipping assign for the region " + hri + " during enable table " @@ -234,7 +239,7 @@ } } } - return regions; + return regionsToAssign; } /** Index: hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (revision 1550346) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (working copy) @@ -880,7 +880,7 @@ for (Map.Entry entry : regions.entrySet()) { assertEquals(regions2.get(entry.getKey()), entry.getValue()); } - } + } /** * Multi-family scenario. Tests forcing split from client and Index: hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java (revision 1550346) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java (working copy) @@ -1159,6 +1159,18 @@ } @Override + boolean assign(ServerName destination, List regions) { + if (enabling) { + for (HRegionInfo region : regions) { + assignmentCount++; + this.regionOnline(region, SERVERNAME_A); + } + return true; + } + return super.assign(destination, regions); + } + + @Override public void assign(List regions) throws IOException, InterruptedException { assignInvoked = (regions != null && regions.size() > 0);