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 2011/03/16 17:55:02 UTC

svn commit: r1082204 - in /hbase/trunk: CHANGES.txt src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java src/test/java/org/apache/hadoop/hbase/catalog/TestMetaReaderEditor.java

Author: jdcryans
Date: Wed Mar 16 16:55:02 2011
New Revision: 1082204

URL: http://svn.apache.org/viewvc?rev=1082204&view=rev
Log:
HBASE-3650  HBA.delete can return too fast

Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
    hbase/trunk/src/test/java/org/apache/hadoop/hbase/catalog/TestMetaReaderEditor.java

Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1082204&r1=1082203&r2=1082204&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Wed Mar 16 16:55:02 2011
@@ -167,6 +167,7 @@ Release 0.90.2 - Unreleased
    HBASE-3639  FSUtils.getRootDir should qualify path
    HBASE-3648  [replication] failover is sloppy with znodes
    HBASE-3613  NPE in MemStoreFlusher
+   HBASE-3650  HBA.delete can return too fast
 
   IMPROVEMENTS
    HBASE-3542  MultiGet methods in Thrift

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java?rev=1082204&r1=1082203&r2=1082204&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java Wed Mar 16 16:55:02 2011
@@ -431,21 +431,14 @@ public class MetaReader {
     }
     HRegionInterface metaServer =
       catalogTracker.waitForMetaServerConnectionDefault();
-    byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
-    Scan scan = new Scan(firstRowInTable);
+    Scan scan = getScanForTableName(Bytes.toBytes(tableName));
     scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
     long scannerid = metaServer.openScanner(
         HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
     try {
       Result data = metaServer.next(scannerid);
       if (data != null && data.size() > 0) {
-        HRegionInfo info = Writables.getHRegionInfo(
-          data.getValue(HConstants.CATALOG_FAMILY,
-              HConstants.REGIONINFO_QUALIFIER));
-        if (info.getTableDesc().getNameAsString().equals(tableName)) {
-          // A region for this table already exists. Ergo table exists.
           return true;
-        }
       }
       return false;
     } finally {
@@ -494,9 +487,8 @@ public class MetaReader {
     HRegionInterface metaServer =
       getCatalogRegionInterface(catalogTracker, tableName);
     List<HRegionInfo> regions = new ArrayList<HRegionInfo>();
-    String tableString = Bytes.toString(tableName);
-    byte[] firstRowInTable = Bytes.toBytes(tableString + ",,");
-    Scan scan = new Scan(firstRowInTable);
+
+    Scan scan = getScanForTableName(tableName);
     scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
     long scannerid =
       metaServer.openScanner(getCatalogRegionNameForTable(tableName), scan);
@@ -507,13 +499,8 @@ public class MetaReader {
           HRegionInfo info = Writables.getHRegionInfo(
               data.getValue(HConstants.CATALOG_FAMILY,
                   HConstants.REGIONINFO_QUALIFIER));
-          if (info.getTableDesc().getNameAsString().equals(tableString)) {
-            // Are we to include split parents in the list?
-            if (excludeOfflinedSplitParents && info.isSplitParent()) continue;
-            regions.add(info);
-          } else {
-            break;
-          }
+          if (excludeOfflinedSplitParents && info.isSplitParent()) continue;
+          regions.add(info);
         }
       }
       return regions;
@@ -523,6 +510,27 @@ public class MetaReader {
   }
 
   /**
+   * This method creates a Scan object that will only scan catalog rows that
+   * belong to the specified table. It doesn't specify any columns.
+   * This is a better alternative to just using a start row and scan until
+   * it hits a new table since that requires parsing the HRI to get the table
+   * name.
+   * @param tableName bytes of table's name
+   * @return configured Scan object
+   */
+  public static Scan getScanForTableName(byte[] tableName) {
+    String strName = Bytes.toString(tableName);
+    // Start key is just the table name with delimiters
+    byte[] startKey = Bytes.toBytes(strName + ",,");
+    // Stop key appends the smallest possible char to the table name
+    byte[] stopKey = Bytes.toBytes(strName + " ,,");
+
+    Scan scan = new Scan(startKey);
+    scan.setStopRow(stopKey);
+    return scan;
+  }
+
+  /**
    * @param catalogTracker
    * @param tableName
    * @return Return list of regioninfos and server addresses.
@@ -545,8 +553,7 @@ public class MetaReader {
       getCatalogRegionInterface(catalogTracker, tableNameBytes);
     List<Pair<HRegionInfo, HServerAddress>> regions =
       new ArrayList<Pair<HRegionInfo, HServerAddress>>();
-    byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
-    Scan scan = new Scan(firstRowInTable);
+    Scan scan = getScanForTableName(tableNameBytes);
     scan.addFamily(HConstants.CATALOG_FAMILY);
     long scannerid =
       metaServer.openScanner(getCatalogRegionNameForTable(tableNameBytes), scan);
@@ -556,12 +563,7 @@ public class MetaReader {
         if (data != null && data.size() > 0) {
           Pair<HRegionInfo, HServerAddress> region = metaRowToRegionPair(data);
           if (region == null) continue;
-          if (region.getFirst().getTableDesc().getNameAsString().equals(
-              tableName)) {
-            regions.add(region);
-          } else {
-            break;
-          }
+          regions.add(region);
         }
       }
       return regions;

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=1082204&r1=1082203&r2=1082204&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Wed Mar 16 16:55:02 2011
@@ -22,8 +22,6 @@ package org.apache.hadoop.hbase.client;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -49,7 +47,6 @@ import org.apache.hadoop.hbase.ipc.HMast
 import org.apache.hadoop.hbase.ipc.HRegionInterface;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
-import org.apache.hadoop.hbase.util.Writables;
 import org.apache.hadoop.ipc.RemoteException;
 
 /**
@@ -371,40 +368,21 @@ public class HBaseAdmin implements Abort
     } catch (RemoteException e) {
       throw RemoteExceptionHandler.decodeRemoteException(e);
     }
-    final int batchCount = this.conf.getInt("hbase.admin.scanner.caching", 10);
     // Wait until all regions deleted
     HRegionInterface server =
       connection.getHRegionConnection(firstMetaServer.getServerAddress());
-    HRegionInfo info = new HRegionInfo();
     for (int tries = 0; tries < (this.numRetries * this.retryLongerMultiplier); tries++) {
       long scannerId = -1L;
       try {
-        Scan scan = new Scan().addColumn(HConstants.CATALOG_FAMILY,
-          HConstants.REGIONINFO_QUALIFIER);
+
+        Scan scan = MetaReader.getScanForTableName(tableName);
+        scan.addColumn(HConstants.CATALOG_FAMILY,
+            HConstants.REGIONINFO_QUALIFIER);
         scannerId = server.openScanner(
           firstMetaServer.getRegionInfo().getRegionName(), scan);
         // Get a batch at a time.
-        Result [] values = server.next(scannerId, batchCount);
-        if (values == null || values.length == 0) {
-          break;
-        }
-        boolean found = false;
-        for (Result r : values) {
-          NavigableMap<byte[], byte[]> infoValues =
-              r.getFamilyMap(HConstants.CATALOG_FAMILY);
-          for (Map.Entry<byte[], byte[]> e : infoValues.entrySet()) {
-            if (Bytes.equals(e.getKey(), HConstants.REGIONINFO_QUALIFIER)) {
-              info = (HRegionInfo) Writables.getWritable(e.getValue(), info);
-              if (Bytes.equals(info.getTableDesc().getName(), tableName)) {
-                found = true;
-              } else {
-                found = false;
-                break;
-              }
-            }
-          }
-        }
-        if (!found) {
+        Result values = server.next(scannerId);
+        if (values == null) {
           break;
         }
       } catch (IOException ex) {

Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/catalog/TestMetaReaderEditor.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/catalog/TestMetaReaderEditor.java?rev=1082204&r1=1082203&r2=1082204&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/catalog/TestMetaReaderEditor.java (original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/catalog/TestMetaReaderEditor.java Wed Mar 16 16:55:02 2011
@@ -130,4 +130,34 @@ public class TestMetaReaderEditor {
       pair.getFirst().getEncodedName());
     LOG.info("Finished " + name);
   }
+
+  // Test for the optimization made in HBASE-3650
+  @Test public void testScanMetaForTable() throws IOException {
+    final String name = "testScanMetaForTable";
+    LOG.info("Started " + name);
+
+    /** Create 5 tables
+     - testScanMetaForTable
+     - testScanMetaForTable0
+     - testScanMetaForTable1
+     - testScanMetaForTable2
+     - testScanMetaForTablf
+    **/
+
+    UTIL.createTable(Bytes.toBytes(name), HConstants.CATALOG_FAMILY);
+    for (int i = 3; i < 3; i ++) {
+      UTIL.createTable(Bytes.toBytes(name+i), HConstants.CATALOG_FAMILY);
+    }
+    // name that is +1 greater than the first one (e+1=f)
+    byte[] greaterName = Bytes.toBytes("testScanMetaForTablf");
+    UTIL.createTable(greaterName, HConstants.CATALOG_FAMILY);
+
+    // Now make sure we only get the regions from 1 of the tables at a time
+
+    assertEquals(1, MetaReader.getTableRegions(ct, Bytes.toBytes(name)).size());
+    for (int i = 3; i < 3; i ++) {
+      assertEquals(1, MetaReader.getTableRegions(ct, Bytes.toBytes(name+i)).size());
+    }
+    assertEquals(1, MetaReader.getTableRegions(ct, greaterName).size());
+  }
 }
\ No newline at end of file