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/04/20 21:05:57 UTC

svn commit: r936032 - in /hadoop/hbase/branches/0.20: ./ src/java/org/apache/hadoop/hbase/ src/java/org/apache/hadoop/hbase/master/ src/java/org/apache/hadoop/hbase/util/

Author: stack
Date: Tue Apr 20 19:05:56 2010
New Revision: 936032

URL: http://svn.apache.org/viewvc?rev=936032&view=rev
Log:
HBASE-2448 Scanner threads are interrupted without acquiring lock properly

Modified:
    hadoop/hbase/branches/0.20/CHANGES.txt
    hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/Chore.java
    hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/BaseScanner.java
    hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ModifyTableMeta.java
    hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ProcessRegionOpen.java
    hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/RegionManager.java
    hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/util/Sleeper.java

Modified: hadoop/hbase/branches/0.20/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/CHANGES.txt?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/CHANGES.txt (original)
+++ hadoop/hbase/branches/0.20/CHANGES.txt Tue Apr 20 19:05:56 2010
@@ -87,6 +87,8 @@ Release 0.20.4 - Unreleased
    HBASE-2451   .META. by-passes cache; BLOCKCACHE=>'false'
    HBASE-2456   deleteChangedReaderObserver spitting warnings after HBASE-2248
    HBASE-2457  RS gets stuck compacting region ad infinitum
+   HBASE-2448  Scanner threads are interrupted without acquiring lock properly
+               (Todd Lipcon via Stack)
 
   IMPROVEMENTS
    HBASE-2180  Bad read performance from synchronizing hfile.fddatainputstream

Modified: hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/Chore.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/Chore.java?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/Chore.java (original)
+++ hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/Chore.java Tue Apr 20 19:05:56 2010
@@ -84,6 +84,15 @@ public abstract class Chore extends Thre
   }
   
   /**
+   * If the thread is currently sleeping, trigger the core to happen immediately.
+   * If it's in the middle of its operation, will begin another operation
+   * immediately after finishing this one.
+   */
+  public void triggerNow() {
+    this.sleeper.skipSleepCycle();
+  }
+  
+  /**
    * Override to run a task before we start looping.
    * @return true if initial chore was successful
    */

Modified: hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/BaseScanner.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/BaseScanner.java?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/BaseScanner.java (original)
+++ hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/BaseScanner.java Tue Apr 20 19:05:56 2010
@@ -589,9 +589,9 @@ abstract class BaseScanner extends Chore
   }
 
   /**
-   * Notify the thread to die at the end of its next run
+   * Interrupt thread regardless of what it's doing
    */
-  public void interruptIfAlive() {
+  public void interruptAndStop() {
     synchronized(scannerLock){
       if (isAlive()) {
         super.interrupt();

Modified: hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ModifyTableMeta.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ModifyTableMeta.java?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ModifyTableMeta.java (original)
+++ hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ModifyTableMeta.java Tue Apr 20 19:05:56 2010
@@ -73,6 +73,6 @@ class ModifyTableMeta extends TableOpera
       updateRegionInfo(server, m.getRegionName(), i);
     }
     // kick off a meta scan right away
-    master.regionManager.metaScannerThread.interrupt();
+    master.regionManager.metaScannerThread.triggerNow();
   }
 }

Modified: hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ProcessRegionOpen.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ProcessRegionOpen.java?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ProcessRegionOpen.java (original)
+++ hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/ProcessRegionOpen.java Tue Apr 20 19:05:56 2010
@@ -100,7 +100,7 @@ class ProcessRegionOpen extends ProcessR
           master.regionManager.putMetaRegionOnline(m);
           // Interrupting the Meta Scanner sleep so that it can
           // process regions right away
-          master.regionManager.metaScannerThread.interrupt();
+          master.regionManager.metaScannerThread.triggerNow();
         }
       }
       // If updated successfully, remove from pending list if the state

Modified: hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/RegionManager.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/RegionManager.java?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/RegionManager.java (original)
+++ hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/master/RegionManager.java Tue Apr 20 19:05:56 2010
@@ -596,11 +596,11 @@ class RegionManager implements HConstant
     if (LOG.isDebugEnabled()) {
       LOG.debug("telling root scanner to stop");
     }
-    rootScannerThread.interruptIfAlive();
+    rootScannerThread.interruptAndStop();
     if (LOG.isDebugEnabled()) {
       LOG.debug("telling meta scanner to stop");
     }
-    metaScannerThread.interruptIfAlive();
+    metaScannerThread.interruptAndStop();
     if (LOG.isDebugEnabled()) {
       LOG.debug("meta and root scanners notified");
     }

Modified: hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/util/Sleeper.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/util/Sleeper.java?rev=936032&r1=936031&r2=936032&view=diff
==============================================================================
--- hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/util/Sleeper.java (original)
+++ hadoop/hbase/branches/0.20/src/java/org/apache/hadoop/hbase/util/Sleeper.java Tue Apr 20 19:05:56 2010
@@ -35,7 +35,10 @@ public class Sleeper {
   private final int period;
   private AtomicBoolean stop;
   private static final long MINIMAL_DELTA_FOR_LOGGING = 10000;
-  
+ 
+  private final Object sleepLock = new Object();
+  private boolean triggerWake = false;
+
   /**
    * @param sleep
    * @param stop
@@ -51,6 +54,17 @@ public class Sleeper {
   public void sleep() {
     sleep(System.currentTimeMillis());
   }
+
+  /**
+   * If currently asleep, stops sleeping; if not asleep, will skip the next
+   * sleep cycle.
+   */
+  public void skipSleepCycle() {
+    synchronized (sleepLock) {
+      triggerWake = true;
+      sleepLock.notify();
+    }
+  }
   
   /**
    * Sleep for period adjusted by passed <code>startTime<code>
@@ -72,7 +86,10 @@ public class Sleeper {
     while (waitTime > 0) {
       long woke = -1;
       try {
-        Thread.sleep(waitTime);
+        synchronized (sleepLock) {
+          if (triggerWake) break;
+          sleepLock.wait(waitTime);
+        }
         woke = System.currentTimeMillis();
         long slept = woke - now;
         if (slept - this.period > MINIMAL_DELTA_FOR_LOGGING) {
@@ -92,5 +109,6 @@ public class Sleeper {
       woke = (woke == -1)? System.currentTimeMillis(): woke;
       waitTime = this.period - (woke - startTime);
     }
+    triggerWake = false;
   }
 }