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 2010/12/02 01:00:30 UTC

svn commit: r1041217 - in /hbase/trunk: CHANGES.txt src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java

Author: stack
Date: Thu Dec  2 00:00:30 2010
New Revision: 1041217

URL: http://svn.apache.org/viewvc?rev=1041217&view=rev
Log:
HBASE-3291 If split happens while regionserver is going down, we can stick open

Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java

Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1041217&r1=1041216&r2=1041217&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Thu Dec  2 00:00:30 2010
@@ -731,7 +731,8 @@ Release 0.90.0 - Unreleased
                of .META.
    HBASE-3294  WARN org.apache.hadoop.hbase.regionserver.Store: Not in set
                (double-remove?) org.apache.hadoop.hbase.regionserver.StoreScanner@76607d3d
-   HBASE-3299   If failed open, we don't output the IOE
+   HBASE-3299  If failed open, we don't output the IOE
+   HBASE-3291  If split happens while regionserver is going down, we can stick open.
 
 
   IMPROVEMENTS

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java?rev=1041217&r1=1041216&r2=1041217&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java Thu Dec  2 00:00:30 2010
@@ -30,6 +30,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -170,10 +171,10 @@ public class HRegionServer implements HR
 
   /**
    * Map of regions currently being served by this region server. Key is the
-   * encoded region name.
+   * encoded region name.  All access should be synchronized.
    */
   protected final Map<String, HRegion> onlineRegions =
-    new ConcurrentHashMap<String, HRegion>();
+    new HashMap<String, HRegion>();
 
   protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
   private final LinkedBlockingQueue<HMsg> outboundMsgs = new LinkedBlockingQueue<HMsg>();
@@ -546,11 +547,11 @@ public class HRegionServer implements HR
       // The main run loop.
       for (int tries = 0; !this.stopped && isHealthy();) {
         if (!isClusterUp()) {
-          if (this.onlineRegions.isEmpty()) {
+          if (isOnlineRegionsEmpty()) {
             stop("Exiting; cluster shutdown set and not carrying any regions");
           } else if (!this.stopping) {
-            closeUserRegions(this.abortRequested);
             this.stopping = true;
+            closeUserRegions(this.abortRequested);
           }
         }
         long now = System.currentTimeMillis();
@@ -660,16 +661,18 @@ public class HRegionServer implements HR
   private void waitOnAllRegionsToClose() {
     // Wait till all regions are closed before going out.
     int lastCount = -1;
-    while (!this.onlineRegions.isEmpty()) {
-      int count = this.onlineRegions.size();
+    while (!isOnlineRegionsEmpty()) {
+      int count = getNumberOfOnlineRegions();
       // Only print a message if the count of regions has changed.
       if (count != lastCount) {
         lastCount = count;
         LOG.info("Waiting on " + count + " regions to close");
         // Only print out regions still closing if a small number else will
         // swamp the log.
-        if (count < 10) {
-          LOG.debug(this.onlineRegions);
+        if (count < 10 && LOG.isDebugEnabled()) {
+          synchronized (this.onlineRegions) {
+            LOG.debug(this.onlineRegions);
+          }
         }
       }
       Threads.sleep(1000);
@@ -721,8 +724,10 @@ public class HRegionServer implements HR
     HServerLoad hsl = new HServerLoad(requestCount.get(),
       (int)(memory.getUsed() / 1024 / 1024),
       (int) (memory.getMax() / 1024 / 1024));
-    for (HRegion r : this.onlineRegions.values()) {
-      hsl.addRegionInfo(createRegionLoad(r));
+    synchronized (this.onlineRegions) {
+      for (HRegion r : this.onlineRegions.values()) {
+        hsl.addRegionInfo(createRegionLoad(r));
+      }
     }
     return hsl;
   }
@@ -884,7 +889,11 @@ public class HRegionServer implements HR
    * @throws IOException
    */
   public HServerLoad.RegionLoad createRegionLoad(final String encodedRegionName) {
-    return createRegionLoad(this.onlineRegions.get(encodedRegionName));
+    HRegion r = null;
+    synchronized (this.onlineRegions) {
+      r = this.onlineRegions.get(encodedRegionName);
+    }
+    return createRegionLoad(r);
   }
 
   /*
@@ -1000,15 +1009,17 @@ public class HRegionServer implements HR
 
     @Override
     protected void chore() {
-      for (HRegion r : this.instance.onlineRegions.values()) {
-        try {
-          if (r != null && r.isMajorCompaction()) {
-            // Queue a compaction. Will recognize if major is needed.
-            this.instance.compactSplitThread.requestCompaction(r, getName()
+      synchronized (this.instance.onlineRegions) {
+        for (HRegion r : this.instance.onlineRegions.values()) {
+          try {
+            if (r != null && r.isMajorCompaction()) {
+              // Queue a compaction. Will recognize if major is needed.
+              this.instance.compactSplitThread.requestCompaction(r, getName()
                 + " requests major compaction");
+            }
+          } catch (IOException e) {
+            LOG.warn("Failed major compaction check on " + r, e);
           }
-        } catch (IOException e) {
-          LOG.warn("Failed major compaction check on " + r, e);
         }
       }
     }
@@ -1491,14 +1502,16 @@ public class HRegionServer implements HR
     HRegion root = null;
     this.lock.writeLock().lock();
     try {
-      for (Map.Entry<String, HRegion> e: onlineRegions.entrySet()) {
-        HRegionInfo hri = e.getValue().getRegionInfo();
-        if (hri.isRootRegion()) {
-          root = e.getValue();
-        } else if (hri.isMetaRegion()) {
-          meta = e.getValue();
+      synchronized (this.onlineRegions) {
+        for (Map.Entry<String, HRegion> e: onlineRegions.entrySet()) {
+          HRegionInfo hri = e.getValue().getRegionInfo();
+          if (hri.isRootRegion()) {
+            root = e.getValue();
+          } else if (hri.isMetaRegion()) {
+            meta = e.getValue();
+          }
+          if (meta != null && root != null) break;
         }
-        if (meta != null && root != null) break;
       }
     } finally {
       this.lock.writeLock().unlock();
@@ -2056,11 +2069,14 @@ public class HRegionServer implements HR
   public boolean closeRegion(HRegionInfo region, final boolean zk)
   throws NotServingRegionException {
     LOG.info("Received close region: " + region.getRegionNameAsString());
-    if (!onlineRegions.containsKey(region.getEncodedName())) {
-      LOG.warn("Received close for region we are not serving; " +
-        region.getEncodedName());
-      throw new NotServingRegionException("Received close for "
+    synchronized (this.onlineRegions) {
+      boolean hasit = this.onlineRegions.containsKey(region.getEncodedName());
+      if (!hasit) {
+        LOG.warn("Received close for region we are not serving; " +
+          region.getEncodedName());
+        throw new NotServingRegionException("Received close for "
           + region.getRegionNameAsString() + " but we are not serving it");
+      }
     }
     return closeRegion(region, false, zk);
   }
@@ -2162,7 +2178,17 @@ public class HRegionServer implements HR
   }
 
   public int getNumberOfOnlineRegions() {
-    return onlineRegions.size();
+    int size = -1;
+    synchronized (this.onlineRegions) {
+      size = this.onlineRegions.size();
+    }
+    return size;
+  }
+
+  boolean isOnlineRegionsEmpty() {
+    synchronized (this.onlineRegions) {
+      return this.onlineRegions.isEmpty();
+    }
   }
 
   /**
@@ -2172,14 +2198,19 @@ public class HRegionServer implements HR
    * @see #getOnlineRegions()
    */
   public Collection<HRegion> getOnlineRegionsLocalContext() {
-    return Collections.unmodifiableCollection(this.onlineRegions.values());
+    synchronized (this.onlineRegions) {
+      Collection<HRegion> regions = this.onlineRegions.values();
+      return Collections.unmodifiableCollection(regions);
+    }
   }
 
   @Override
   public void addToOnlineRegions(HRegion region) {
     lock.writeLock().lock();
     try {
-      onlineRegions.put(region.getRegionInfo().getEncodedName(), region);
+      synchronized (this.onlineRegions) {
+        this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);
+      }
     } finally {
       lock.writeLock().unlock();
     }
@@ -2190,7 +2221,9 @@ public class HRegionServer implements HR
     this.lock.writeLock().lock();
     HRegion toReturn = null;
     try {
-      toReturn = onlineRegions.remove(encodedName);
+      synchronized (this.onlineRegions) {
+        toReturn = this.onlineRegions.remove(encodedName);
+      }
     } finally {
       this.lock.writeLock().unlock();
     }
@@ -2220,7 +2253,11 @@ public class HRegionServer implements HR
 
   @Override
   public HRegion getFromOnlineRegions(final String encodedRegionName) {
-    return onlineRegions.get(encodedRegionName);
+    HRegion r = null;
+    synchronized (this.onlineRegions) {
+      r = this.onlineRegions.get(encodedRegionName);
+    }
+    return r;
   }
 
   /**
@@ -2313,7 +2350,9 @@ public class HRegionServer implements HR
     // TODO: is this locking necessary?
     lock.readLock().lock();
     try {
-      regionsToCheck.addAll(this.onlineRegions.values());
+      synchronized (this.onlineRegions) {
+        regionsToCheck.addAll(this.onlineRegions.values());
+      }
     } finally {
       lock.readLock().unlock();
     }
@@ -2446,12 +2485,14 @@ public class HRegionServer implements HR
   }
 
   public HRegionInfo[] getRegionsAssignment() throws IOException {
-    HRegionInfo[] regions = new HRegionInfo[onlineRegions.size()];
-    Iterator<HRegion> ite = onlineRegions.values().iterator();
-    for (int i = 0; ite.hasNext(); i++) {
-      regions[i] = ite.next().getRegionInfo();
+    synchronized (this.onlineRegions) {
+      HRegionInfo [] regions = new HRegionInfo[getNumberOfOnlineRegions()];
+      Iterator<HRegion> ite = onlineRegions.values().iterator();
+      for (int i = 0; ite.hasNext(); i++) {
+        regions[i] = ite.next().getRegionInfo();
+      }
+      return regions;
     }
-    return regions;
   }
 
   /** {@inheritDoc} */

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java?rev=1041217&r1=1041216&r2=1041217&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/SplitTransaction.java Thu Dec  2 00:00:30 2010
@@ -301,6 +301,15 @@ public class SplitTransaction {
   void openDaughterRegion(final Server server,
       final RegionServerServices services, final HRegion daughter)
   throws IOException, KeeperException {
+    if (server.isStopped() || services.isStopping()) {
+      MetaEditor.addDaughter(server.getCatalogTracker(),
+        daughter.getRegionInfo(), null);
+      LOG.info("Not opening daughter " +
+        daughter.getRegionInfo().getRegionNameAsString() +
+        " because stopping=" + services.isStopping() + ", stopped=" +
+        server.isStopped());
+      return;
+    }
     HRegionInfo hri = daughter.getRegionInfo();
     LoggingProgressable reporter =
       new LoggingProgressable(hri, server.getConfiguration());