You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by jd...@apache.org on 2010/06/23 22:49:34 UTC

svn commit: r957335 - in /hbase/branches/0.89.20100621: CHANGES.txt src/main/java/org/apache/hadoop/hbase/client/HTable.java src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java src/test/java/org/apache/hadoop/hbase/client/TestScannerTimeout.java

Author: jdcryans
Date: Wed Jun 23 20:49:33 2010
New Revision: 957335

URL: http://svn.apache.org/viewvc?rev=957335&view=rev
Log:
Scan doesn't recover from region server failure

Modified:
    hbase/branches/0.89.20100621/CHANGES.txt
    hbase/branches/0.89.20100621/src/main/java/org/apache/hadoop/hbase/client/HTable.java
    hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
    hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/client/TestScannerTimeout.java

Modified: hbase/branches/0.89.20100621/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/branches/0.89.20100621/CHANGES.txt?rev=957335&r1=957334&r2=957335&view=diff
==============================================================================
--- hbase/branches/0.89.20100621/CHANGES.txt (original)
+++ hbase/branches/0.89.20100621/CHANGES.txt Wed Jun 23 20:49:33 2010
@@ -11,6 +11,7 @@ Development Release 0.89.20100621
                the region
    HBASE-2617  Load balancer falls into pathological state if one server
                under average - slop; endless churn
+   HBASE-2772  Scan doesn't recover from region server failure
 
 Release 0.21.0 - Unreleased
   INCOMPATIBLE CHANGES

Modified: hbase/branches/0.89.20100621/src/main/java/org/apache/hadoop/hbase/client/HTable.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89.20100621/src/main/java/org/apache/hadoop/hbase/client/HTable.java?rev=957335&r1=957334&r2=957335&view=diff
==============================================================================
--- hbase/branches/0.89.20100621/src/main/java/org/apache/hadoop/hbase/client/HTable.java (original)
+++ hbase/branches/0.89.20100621/src/main/java/org/apache/hadoop/hbase/client/HTable.java Wed Jun 23 20:49:33 2010
@@ -942,19 +942,24 @@ public class HTable implements HTableInt
               values = getConnection().getRegionServerWithRetries(callable);
             }
           } catch (DoNotRetryIOException e) {
-            long timeout = lastNext + scannerTimeout;
-            if (e instanceof UnknownScannerException &&
-                timeout < System.currentTimeMillis()) {
-              long elapsed = System.currentTimeMillis() - lastNext;
-              ScannerTimeoutException ex = new ScannerTimeoutException(
-                  elapsed + "ms passed since the last invocation, " +
-                      "timeout is currently set to " + scannerTimeout);
-              ex.initCause(e);
-              throw ex;
-            }
-            Throwable cause = e.getCause();
-            if (cause == null || !(cause instanceof NotServingRegionException)) {
-              throw e;
+            if (e instanceof UnknownScannerException) {
+              long timeout = lastNext + scannerTimeout;
+              // If we are over the timeout, throw this exception to the client
+              // Else, it's because the region moved and we used the old id
+              // against the new region server; reset the scanner.
+              if (timeout < System.currentTimeMillis()) {
+                long elapsed = System.currentTimeMillis() - lastNext;
+                ScannerTimeoutException ex = new ScannerTimeoutException(
+                    elapsed + "ms passed since the last invocation, " +
+                        "timeout is currently set to " + scannerTimeout);
+                ex.initCause(e);
+                throw ex;
+              }
+            } else {
+              Throwable cause = e.getCause();
+              if (cause == null || !(cause instanceof NotServingRegionException)) {
+                throw e;
+              }
             }
             // Else, its signal from depths of ScannerCallable that we got an
             // NSRE on a next and that we need to reset the scanner.

Modified: hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java?rev=957335&r1=957334&r2=957335&view=diff
==============================================================================
--- hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java (original)
+++ hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/MiniHBaseCluster.java Wed Jun 23 20:49:33 2010
@@ -386,15 +386,25 @@ public class MiniHBaseCluster {
 
   /**
    * @return Index into List of {@link MiniHBaseCluster#getRegionServerThreads()}
-   * of HRS carrying .META.  Returns -1 if none found.
+   * of HRS carrying regionName. Returns -1 if none found.
    */
   public int getServerWithMeta() {
+    return getServerWith(HRegionInfo.FIRST_META_REGIONINFO.getRegionName());
+  }
+
+  /**
+   * Get the location of the specified region
+   * @param regionName Name of the region in bytes
+   * @return Index into List of {@link MiniHBaseCluster#getRegionServerThreads()}
+   * of HRS carrying .META.. Returns -1 if none found.
+   */
+  public int getServerWith(byte[] regionName) {
     int index = -1;
     int count = 0;
     for (JVMClusterUtil.RegionServerThread rst: getRegionServerThreads()) {
       HRegionServer hrs = rst.getRegionServer();
       HRegion metaRegion =
-        hrs.getOnlineRegion(HRegionInfo.FIRST_META_REGIONINFO.getRegionName());
+        hrs.getOnlineRegion(regionName);
       if (metaRegion != null) {
         index = count;
         break;

Modified: hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/client/TestScannerTimeout.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/client/TestScannerTimeout.java?rev=957335&r1=957334&r2=957335&view=diff
==============================================================================
--- hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/client/TestScannerTimeout.java (original)
+++ hbase/branches/0.89.20100621/src/test/java/org/apache/hadoop/hbase/client/TestScannerTimeout.java Wed Jun 23 20:49:33 2010
@@ -23,7 +23,11 @@ public class TestScannerTimeout {
       TEST_UTIL = new HBaseTestingUtility();
 
   final Log LOG = LogFactory.getLog(getClass());
-  private final byte[] someBytes = Bytes.toBytes("f");
+  private final static byte[] SOME_BYTES = Bytes.toBytes("f");
+  private final static byte[] TABLE_NAME = Bytes.toBytes("t");
+  private final static int NB_ROWS = 10;
+  private final static int SCANNER_TIMEOUT = 6000;
+  private static HTable table;
 
    /**
    * @throws java.lang.Exception
@@ -31,8 +35,14 @@ public class TestScannerTimeout {
   @BeforeClass
   public static void setUpBeforeClass() throws Exception {
     Configuration c = TEST_UTIL.getConfiguration();
-    c.setInt("hbase.regionserver.lease.period", 1000);
-    TEST_UTIL.startMiniCluster(1);
+    c.setInt("hbase.regionserver.lease.period", SCANNER_TIMEOUT);
+    TEST_UTIL.startMiniCluster(2);
+    table = TEST_UTIL.createTable(Bytes.toBytes("t"), SOME_BYTES);
+     for (int i = 0; i < NB_ROWS; i++) {
+      Put put = new Put(Bytes.toBytes(i));
+      put.add(SOME_BYTES, SOME_BYTES, SOME_BYTES);
+      table.put(put);
+    }
   }
 
   /**
@@ -48,13 +58,7 @@ public class TestScannerTimeout {
    */
   @Before
   public void setUp() throws Exception {
-  }
-
-  /**
-   * @throws java.lang.Exception
-   */
-  @After
-  public void tearDown() throws Exception {
+    TEST_UTIL.ensureSomeRegionServersAvailable(2);
   }
 
   /**
@@ -63,22 +67,16 @@ public class TestScannerTimeout {
    */
   @Test
   public void test2481() throws Exception {
-    int initialCount = 10;
-    HTable t = TEST_UTIL.createTable(Bytes.toBytes("t"), someBytes);
-    for (int i = 0; i < initialCount; i++) {
-      Put put = new Put(Bytes.toBytes(i));
-      put.add(someBytes, someBytes, someBytes);
-      t.put(put);
-    }
     Scan scan = new Scan();
-    ResultScanner r = t.getScanner(scan);
+    ResultScanner r = table.getScanner(scan);
     int count = 0;
     try {
       Result res = r.next();
       while (res != null) {
         count++;
         if (count == 5) {
-          Thread.sleep(1500);
+          // Sleep just a bit more to be sure
+          Thread.sleep(SCANNER_TIMEOUT+100);
         }
         res = r.next();
       }
@@ -88,4 +86,24 @@ public class TestScannerTimeout {
     }
     fail("We should be timing out");
   }
+
+  /**
+   * Test that scanner can continue even if the region server it was reading
+   * from failed. Before 2772, it reused the same scanner id.
+   * @throws Exception
+   */
+  @Test
+  public void test2772() throws Exception {
+    int rs = TEST_UTIL.getHBaseCluster().getServerWith(
+        TEST_UTIL.getHBaseCluster().getRegions(
+            TABLE_NAME).get(0).getRegionName());
+    Scan scan = new Scan();
+    ResultScanner r = table.getScanner(scan);
+    // This takes exactly 5 seconds
+    TEST_UTIL.getHBaseCluster().getRegionServer(rs).abort("die!");
+    Result[] results = r.next(NB_ROWS);
+    assertEquals(NB_ROWS, results.length);
+    r.close();
+
+  }
 }