Author: ramkrishna
Date: Thu Feb 16 17:09:55 2012
New Revision: 1245087

URL: http://svn.apache.org/viewvc?rev=1245087&view=rev
Log:
HBASE-5396 Handle the regions in regionPlans while processing 
ServerShutdownHandler (Jieshan)

Modified:
    hbase/branches/0.90/CHANGES.txt
    
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
    
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java

Modified: hbase/branches/0.90/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.90/CHANGES.txt?rev=1245087&r1=1245086&r2=1245087&view=diff
==============================================================================
--- hbase/branches/0.90/CHANGES.txt (original)
+++ hbase/branches/0.90/CHANGES.txt Thu Feb 16 17:09:55 2012
@@ -47,6 +47,7 @@ Release 0.90.6 - Unreleased
    HBASE-5377  Fix licenses on the 0.90 branch.
    HBASE-5379  Backport HBASE-4287 to 0.90 - If region opening fails, try to 
transition region back to
                "offline" in ZK
+   HBASE-5396  Handle the regions in regionPlans while processing 
ServerShutdownHandler(Jieshan)
 
   IMPROVEMENT
    HBASE-5102  Change the default value of the property 
"hbase.connection.per.config" to false in

Modified: 
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java?rev=1245087&r1=1245086&r2=1245087&view=diff
==============================================================================
--- 
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
 (original)
+++ 
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
 Thu Feb 16 17:09:55 2012
@@ -966,6 +966,27 @@ public class AssignmentManager extends Z
     LOG.debug("Bulk assigning done for " + destination.getServerName());
   }
 
+  public boolean isRegionOnline(HRegionInfo hri) {
+    HServerInfo hsi = null;
+    synchronized (this.regions) {
+      hsi = this.regions.get(hri);
+      if (hsi == null) {
+        return false;
+      }
+      if (this.isServerOnline(hsi.getServerName())) {
+        return true;
+      } else {
+        // Remove the assignment mapping for hsi.
+        Set<HRegionInfo> hriSet = this.servers.get(hsi);
+        if (hriSet != null) {
+          hriSet.remove(hri);
+        }
+        this.regions.remove(hri);
+        return false;
+      }
+    }
+  }
+  
   protected void setEnabledTable(String tableName) {
     try {
       this.zkTable.setEnabledTable(tableName);
@@ -2087,10 +2108,13 @@ public class AssignmentManager extends Z
 
   /**
    * Process shutdown server removing any assignments.
+   * 
    * @param hsi Server that went down.
-   * @return list of regions in transition on this server
+   * @return list of regions in transition and region plans on this server
    */
-  public List<RegionState> processServerShutdown(final HServerInfo hsi) {
+  public RegionsOnDeadServer processServerShutdown(final HServerInfo hsi) {
+    RegionsOnDeadServer regionsOnDeadServer = new RegionsOnDeadServer();
+    Set<HRegionInfo> regionsFromRegionPlansForServer = new 
HashSet<HRegionInfo>();
     // Clean out any existing assignment plans for this server
     synchronized (this.regionPlans) {
       for (Iterator <Map.Entry<String, RegionPlan>> i =
@@ -2099,11 +2123,16 @@ public class AssignmentManager extends Z
         HServerInfo otherHsi = e.getValue().getDestination();
         // The HSI will be null if the region is planned for a random assign.
         if (otherHsi != null && otherHsi.equals(hsi)) {
+          // Store the related regions in regionPlans.
+          regionsFromRegionPlansForServer.add(e.getValue().getRegionInfo());
           // Use iterator's remove else we'll get CME
           i.remove();
         }
       }
     }
+    
+    regionsOnDeadServer
+        .setRegionsFromRegionPlansForServer(regionsFromRegionPlansForServer);
     // TODO: Do we want to sync on RIT here?
     // Remove this server from map of servers to regions, and remove all 
regions
     // of this server from online map of regions.
@@ -2112,8 +2141,9 @@ public class AssignmentManager extends Z
     synchronized (this.regions) {
       Set<HRegionInfo> assignedRegions = this.servers.remove(hsi);
       if (assignedRegions == null || assignedRegions.isEmpty()) {
+        regionsOnDeadServer.setRegionsInTransition(rits);
         // No regions on this server, we are done, return empty list of RITs
-        return rits;
+        return regionsOnDeadServer;
       }
       deadRegions = new TreeSet<HRegionInfo>(assignedRegions);
       for (HRegionInfo region : deadRegions) {
@@ -2130,7 +2160,8 @@ public class AssignmentManager extends Z
         }
       }
     }
-    return rits;
+    regionsOnDeadServer.setRegionsInTransition(rits);
+    return regionsOnDeadServer;
   }
 
   /**
@@ -2379,4 +2410,30 @@ public class AssignmentManager extends Z
   public boolean isServerOnline(String serverName) {
     return this.serverManager.isServerOnline(serverName);
   }
+
+  /**
+   * Store the related regions on a dead server, used by processServerShutdown.
+   */
+  public static class RegionsOnDeadServer {
+    // The regions which being processed on this dead server.
+    private Set<HRegionInfo> regionsFromRegionPlansForServer = null;
+    private List<RegionState> regionsInTransition = null;
+
+    public Set<HRegionInfo> getRegionsFromRegionPlansForServer() {
+      return regionsFromRegionPlansForServer;
+    }
+
+    public void setRegionsFromRegionPlansForServer(
+        Set<HRegionInfo> regionsFromRegionPlansForServer) {
+      this.regionsFromRegionPlansForServer = regionsFromRegionPlansForServer;
+    }
+
+    public List<RegionState> getRegionsInTransition() {
+      return regionsInTransition;
+    }
+
+    public void setRegionsInTransition(List<RegionState> regionsInTransition) {
+      this.regionsInTransition = regionsInTransition;
+    }
+  }
 }

Modified: 
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java
URL: 
http://svn.apache.org/viewvc/hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java?rev=1245087&r1=1245086&r2=1245087&view=diff
==============================================================================
--- 
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java
 (original)
+++ 
hbase/branches/0.90/src/main/java/org/apache/hadoop/hbase/master/handler/ServerShutdownHandler.java
 Thu Feb 16 17:09:55 2012
@@ -20,15 +20,17 @@
 package org.apache.hadoop.hbase.master.handler;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableMap;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
-import org.apache.hadoop.hbase.HServerAddress;
 import org.apache.hadoop.hbase.HServerInfo;
 import org.apache.hadoop.hbase.Server;
 import org.apache.hadoop.hbase.catalog.CatalogTracker;
@@ -38,6 +40,7 @@ import org.apache.hadoop.hbase.client.Re
 import org.apache.hadoop.hbase.executor.EventHandler;
 import org.apache.hadoop.hbase.master.AssignmentManager;
 import org.apache.hadoop.hbase.master.AssignmentManager.RegionState;
+import org.apache.hadoop.hbase.master.AssignmentManager.RegionsOnDeadServer;
 import org.apache.hadoop.hbase.master.DeadServer;
 import org.apache.hadoop.hbase.master.MasterServices;
 import org.apache.hadoop.hbase.master.ServerManager;
@@ -158,9 +161,14 @@ public class ServerShutdownHandler exten
       // doing after log splitting.  Could do some states before -- OPENING?
       // OFFLINE? -- and then others after like CLOSING that depend on log
       // splitting.
-      List<RegionState> regionsInTransition =
-        this.services.getAssignmentManager().processServerShutdown(this.hsi);
-    
+      Set<HRegionInfo> regionsFromRegionPlansForServer = new 
HashSet<HRegionInfo>();
+      List<RegionState> regionsInTransition = new ArrayList<RegionState>();
+      RegionsOnDeadServer regionsOnDeadServer = this.services
+          .getAssignmentManager().processServerShutdown(this.hsi);
+      regionsFromRegionPlansForServer = regionsOnDeadServer
+          .getRegionsFromRegionPlansForServer();
+      regionsInTransition = regionsOnDeadServer.getRegionsInTransition();
+
       // Assign root and meta if we were carrying them.
       if (isCarryingRoot()) { // -ROOT-
         LOG.info("Server " + serverName + " was carrying ROOT. Trying to 
assign.");
@@ -207,32 +215,44 @@ public class ServerShutdownHandler exten
         " regions(s) that are already in transition)");
     
       // Iterate regions that were on this server and assign them
-      for (Map.Entry<HRegionInfo, Result> e : hris.entrySet()) {
-        if (processDeadRegion(e.getKey(), e.getValue(),
-            this.services.getAssignmentManager(),
-            this.server.getCatalogTracker())) {
-          RegionState rit = this.services.getAssignmentManager()
-              .isRegionInTransition(e.getKey());
-          Pair<HRegionInfo, HServerInfo> p =
-            this.services
-              .getAssignmentManager().getAssignment(
-                  e.getKey().getEncodedNameAsBytes());
-          
-          if (rit != null && !rit.isClosing() && !rit.isPendingClose()) {
-            // Skip regions that were in transition unless CLOSING or
-            // PENDING_CLOSE
-            LOG.info("Skip assigning region " + rit.toString());
-          } else if ((p != null) && (p.getSecond() != null)
-              && (p.getSecond().equals(this.hsi))) {
-            LOG.debug("Skip assigning region "
-                + e.getKey().getRegionNameAsString()
-                + " because it has been opened in "
-                + p.getSecond());
-          } else {
-            this.services.getAssignmentManager().assign(e.getKey(), true);
+      if (hris != null) {
+        for (Map.Entry<HRegionInfo, Result> e : hris.entrySet()) {
+          if (processDeadRegion(e.getKey(), e.getValue(),
+              this.services.getAssignmentManager(),
+              this.server.getCatalogTracker())) {
+            RegionState rit = this.services.getAssignmentManager()
+                .isRegionInTransition(e.getKey());
+            Pair<HRegionInfo, HServerInfo> p = this.services
+                .getAssignmentManager().getAssignment(
+                    e.getKey().getEncodedNameAsBytes());
+
+            if (rit != null && !rit.isClosing() && !rit.isPendingClose()
+                && !regionsFromRegionPlansForServer.contains(rit.getRegion())) 
{
+              // Skip regions that were in transition unless CLOSING or
+              // PENDING_CLOSE
+              LOG.info("Skip assigning region " + rit.toString());
+            } else if ((p != null) && (p.getSecond() != null)
+                && !(p.getSecond().equals(this.hsi))) {
+              LOG.debug("Skip assigning region "
+                  + e.getKey().getRegionNameAsString()
+                  + " because it has been opened in " + p.getSecond());
+            } else {
+              this.services.getAssignmentManager().assign(e.getKey(), true);
+              regionsFromRegionPlansForServer.remove(e.getKey());
+            }
           }
         }
       }
+      
+      int reassignedPlans = 0;
+      for (HRegionInfo hri : regionsFromRegionPlansForServer) {
+        if (!this.services.getAssignmentManager().isRegionOnline(hri)) {
+          this.services.getAssignmentManager().assign(hri, true);
+          reassignedPlans++;
+        }
+      }
+      LOG.info(reassignedPlans + " regions which planned to open on "
+          + this.hsi.getServerName() + " be re-assigned.");
     } finally {
       this.deadServers.finish(serverName);
     }


Reply via email to