Index: src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
===================================================================
--- src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (revision 1023101)
+++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (working copy)
@@ -1932,6 +1932,7 @@
public void openRegion(HRegionInfo region) {
LOG.info("Received request to open region: " +
region.getRegionNameAsString());
+ if (this.stopped) throw new RegionServerStoppedException();
if (region.isRootRegion()) {
this.service.submit(new OpenRootHandler(this, this, region));
} else if(region.isMetaRegion()) {
Index: src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerClosedException.java
===================================================================
--- src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerClosedException.java (revision 0)
+++ src/main/java/org/apache/hadoop/hbase/regionserver/RegionServerClosedException.java (revision 0)
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2010 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.regionserver;
+
+import org.apache.hadoop.hbase.DoNotRetryIOException;
+
+/**
+ * Thrown by the region server when it is shutting down state.
+ */
+@SuppressWarnings("serial")
+public class RegionServerClosedException extends DoNotRetryIOException {
+}
\ No newline at end of file
Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
===================================================================
--- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1023101)
+++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy)
@@ -682,6 +682,7 @@
private void assign(final RegionState state) {
if (!setOfflineInZooKeeper(state)) return;
RegionPlan plan = getRegionPlan(state);
+ if (plan == null) return; // Should get reassigned later when RIT times out.
try {
LOG.debug("Assigning region " + state.getRegion().getRegionNameAsString() +
" to " + plan.getDestination().getServerName());
@@ -696,6 +697,10 @@
// Clean out plan we failed execute and one that doesn't look like it'll
// succeed anyways; we need a new plan!
this.regionPlans.remove(state.getRegion().getEncodedName());
+ // Put in place a new plan and reassign. Calling getRegionPlan will add
+ // a plan if none exists (We removed it in line above).
+ if (getRegionPlan(state) == null) return;
+ assign(state);
}
}
@@ -729,14 +734,32 @@
/**
* @param state
- * @return Plan for passed state (If none currently, it creates one)
+ * @return Plan for passed state (If none currently, it creates one or
+ * if no servers to assign, it returns null).
*/
RegionPlan getRegionPlan(final RegionState state) {
+ return getRegionPlan(state, null);
+ }
+
+ /**
+ * @param state
+ * @param serverToExclude Server to exclude (we know its bad). Pass null if
+ * all servers are thought to be assignable.
+ * @return Plan for passed state (If none currently, it creates one or
+ * if no servers to assign, it returns null).
+ */
+ RegionPlan getRegionPlan(final RegionState state,
+ final HServerInfo serverToExclude) {
// Pickup existing plan or make a new one
String encodedName = state.getRegion().getEncodedName();
+ List servers = this.serverManager.getOnlineServersList();
+ // The remove below hinges on the fact that the call to
+ // serverManager.getOnlineServersList() returns a copy
+ if (serverToExclude != null) servers.remove(serverToExclude);
+ if (servers.size() < 0) return null;
RegionPlan newPlan = new RegionPlan(state.getRegion(), null,
- LoadBalancer.randomAssignment(serverManager.getOnlineServersList()));
- RegionPlan existingPlan = regionPlans.putIfAbsent(encodedName, newPlan);
+ LoadBalancer.randomAssignment(servers));
+ RegionPlan existingPlan = this.regionPlans.putIfAbsent(encodedName, newPlan);
RegionPlan plan = null;
if (existingPlan == null) {
LOG.debug("No previous transition plan for " +
@@ -744,7 +767,7 @@
" so generated a random one; " + newPlan + "; " +
serverManager.countOfRegionServers() +
" (online=" + serverManager.getOnlineServers().size() +
- ") available servers");
+ ", exclude=" + serverToExclude + ") available servers");
plan = newPlan;
} else {
LOG.debug("Using preexisting plan=" + existingPlan);