Author: jmhsieh
Date: Thu Apr  4 15:31:26 2013
New Revision: 1464596

URL: http://svn.apache.org/r1464596
Log:
HBASE-8262 Add testcase to verify HBASE-7678's empty region split semantics 
change

Modified:
    
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
    
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java

Modified: 
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java?rev=1464596&r1=1464595&r2=1464596&view=diff
==============================================================================
--- 
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
 (original)
+++ 
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
 Thu Apr  4 15:31:26 2013
@@ -49,18 +49,19 @@ import org.apache.hadoop.fs.PathFilter;
 import org.apache.hadoop.fs.permission.FsAction;
 import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.hbase.ClusterId;
-import org.apache.hadoop.hbase.exceptions.DeserializationException;
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HDFSBlocksDistribution;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.RemoteExceptionHandler;
+import org.apache.hadoop.hbase.exceptions.DeserializationException;
 import org.apache.hadoop.hbase.exceptions.FileSystemVersionException;
 import org.apache.hadoop.hbase.master.HMaster;
 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
 import org.apache.hadoop.hbase.protobuf.generated.FSProtos;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hdfs.DistributedFileSystem;
+import org.apache.hadoop.hdfs.protocol.FSConstants;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.io.SequenceFile;
 import org.apache.hadoop.security.AccessControlException;
@@ -1311,6 +1312,57 @@ public abstract class FSUtils {
     return getRootDir(conf).getFileSystem(conf);
   }
 
+
+  /**
+   * Runs through the HBase rootdir/tablename and creates a reverse lookup map 
for
+   * table StoreFile names to the full Path.
+   * <br>
+   * Example...<br>
+   * Key = 3944417774205889744  <br>
+   * Value = 
hdfs://localhost:51169/user/userid/-ROOT-/70236052/info/3944417774205889744
+   *
+   * @param map map to add values.  If null, this method will create and 
populate one to return
+   * @param fs  The file system to use.
+   * @param hbaseRootDir  The root directory to scan.
+   * @param tablename name of the table to scan.
+   * @return Map keyed by StoreFile name with a value of the full Path.
+   * @throws IOException When scanning the directory fails.
+   */
+  public static Map<String, Path> getTableStoreFilePathMap(Map<String, Path> 
map, 
+    final FileSystem fs, final Path hbaseRootDir, byte[] tablename)
+  throws IOException {
+    if (map == null) {
+      map = new HashMap<String, Path>();
+    }
+
+    // only include the directory paths to tables
+    Path tableDir = new Path(hbaseRootDir, Bytes.toString(tablename));
+    // Inside a table, there are compaction.dir directories to skip.  
Otherwise, all else
+    // should be regions. 
+    PathFilter df = new BlackListDirFilter(fs, 
HConstants.HBASE_NON_TABLE_DIRS);
+    FileStatus[] regionDirs = fs.listStatus(tableDir);
+    for (FileStatus regionDir : regionDirs) {
+      Path dd = regionDir.getPath();
+      if (dd.getName().equals(HConstants.HREGION_COMPACTIONDIR_NAME)) {
+        continue;
+      }
+      // else its a region name, now look in region for families
+      FileStatus[] familyDirs = fs.listStatus(dd, df);
+      for (FileStatus familyDir : familyDirs) {
+        Path family = familyDir.getPath();
+        // now in family, iterate over the StoreFiles and
+        // put in map
+        FileStatus[] familyStatus = fs.listStatus(family);
+        for (FileStatus sfStatus : familyStatus) {
+          Path sf = sfStatus.getPath();
+          map.put( sf.getName(), sf);
+        }
+      }
+    }
+    return map;
+  }
+
+  
   /**
    * Runs through the HBase rootdir and creates a reverse lookup map for
    * table StoreFile names to the full Path.
@@ -1336,28 +1388,8 @@ public abstract class FSUtils {
     PathFilter df = new BlackListDirFilter(fs, 
HConstants.HBASE_NON_TABLE_DIRS);
     FileStatus [] tableDirs = fs.listStatus(hbaseRootDir, df);
     for (FileStatus tableDir : tableDirs) {
-      // Inside a table, there are compaction.dir directories to skip.  
Otherwise, all else
-      // should be regions. 
-      FileStatus[] regionDirs = fs.listStatus(tableDir.getPath(), df);
-      for (FileStatus regionDir : regionDirs) {
-        Path dd = regionDir.getPath();
-        if (dd.getName().equals(HConstants.HREGION_COMPACTIONDIR_NAME)) {
-          continue;
-        }
-        // else its a region name, now look in region for families
-        FileStatus[] familyDirs = fs.listStatus(dd, df);
-        for (FileStatus familyDir : familyDirs) {
-          Path family = familyDir.getPath();
-          // now in family, iterate over the StoreFiles and
-          // put in map
-          FileStatus[] familyStatus = fs.listStatus(family);
-          for (FileStatus sfStatus : familyStatus) {
-            Path sf = sfStatus.getPath();
-            map.put( sf.getName(), sf);
-          }
-
-        }
-      }
+      byte[] tablename = Bytes.toBytes(tableDir.getPath().getName());
+      getTableStoreFilePathMap(map, fs, hbaseRootDir, tablename);
     }
       return map;
   }

Modified: 
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
URL: 
http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java?rev=1464596&r1=1464595&r2=1464596&view=diff
==============================================================================
--- 
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
 (original)
+++ 
hbase/trunk/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestSplitTransactionOnCluster.java
 Thu Apr  4 15:31:26 2013
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertTru
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
@@ -34,6 +35,8 @@ import java.util.concurrent.CountDownLat
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseTestingUtility;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
@@ -59,6 +62,8 @@ import org.apache.hadoop.hbase.master.Re
 import org.apache.hadoop.hbase.master.handler.SplitRegionHandler;
 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.hadoop.hbase.util.HBaseFsck;
 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
 import org.apache.hadoop.hbase.util.Threads;
 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
@@ -67,8 +72,8 @@ import org.apache.hadoop.hbase.zookeeper
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.KeeperException.NodeExistsException;
 import org.apache.zookeeper.data.Stat;
-import org.junit.AfterClass;
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -640,6 +645,67 @@ public class TestSplitTransactionOnClust
     admin.flush(tableName);
   }
 
+  /**
+   * If a table has regions that have no store files in a region, they should 
split successfully
+   * into two regions with no store files.
+   */
+  @Test
+  public void testSplitRegionWithNoStoreFiles()
+      throws Exception {
+    final byte[] tableName = Bytes.toBytes("testSplitRegionWithNoStoreFiles");
+    // Create table then get the single region for our new table.
+    createTableAndWait(tableName, HConstants.CATALOG_FAMILY);
+    List<HRegion> regions = cluster.getRegions(tableName);
+    HRegionInfo hri = getAndCheckSingleTableRegion(regions);
+    ensureTableRegionNotOnSameServerAsMeta(admin, hri);
+    int regionServerIndex = 
cluster.getServerWith(regions.get(0).getRegionName());
+    HRegionServer regionServer = cluster.getRegionServer(regionServerIndex);
+    // Turn off balancer so it doesn't cut in and mess up our placements.
+    this.admin.setBalancerRunning(false, true);
+    // Turn off the meta scanner so it don't remove parent on us.
+    cluster.getMaster().setCatalogJanitorEnabled(false);
+    try {
+      // Precondition: we created a table with no data, no store files.
+      printOutRegions(regionServer, "Initial regions: ");
+      Configuration conf = cluster.getConfiguration();
+      HBaseFsck.debugLsr(conf, new Path("/"));
+      Path rootDir = FSUtils.getRootDir(conf);
+      FileSystem fs = TESTING_UTIL.getDFSCluster().getFileSystem();
+      Map<String, Path> storefiles =
+          FSUtils.getTableStoreFilePathMap(null, fs, rootDir, tableName);
+      assertEquals("Expected nothing but found " + storefiles.toString(), 
storefiles.size(), 0);
+
+      // find a splittable region.  Refresh the regions list
+      regions = cluster.getRegions(tableName);
+      final HRegion region = findSplittableRegion(regions);
+      assertTrue("not able to find a splittable region", region != null);
+
+      // Now split.
+      SplitTransaction st = new MockedSplitTransaction(region, 
Bytes.toBytes("row2"));
+      try {
+        st.prepare();
+        st.execute(regionServer, regionServer);
+      } catch (IOException e) {
+        fail("Split execution should have succeeded with no exceptions 
thrown");
+      }
+
+      // Postcondition: split the table with no store files into two regions, 
but still have not
+      // store files
+      List<HRegion> daughters = cluster.getRegions(tableName);
+      assertTrue(daughters.size() == 2);
+
+      // check dirs
+      HBaseFsck.debugLsr(conf, new Path("/"));
+      Map<String, Path> storefilesAfter =
+          FSUtils.getTableStoreFilePathMap(null, fs, rootDir, tableName);
+      assertEquals("Expected nothing but found " + storefilesAfter.toString(),
+          storefilesAfter.size(), 0);
+    } finally {
+      admin.setBalancerRunning(true, false);
+      cluster.getMaster().setCatalogJanitorEnabled(true);
+    }
+  }
+
   private void testSplitBeforeSettingSplittingInZKInternals() throws Exception 
{
     final byte[] tableName = 
Bytes.toBytes("testSplitBeforeSettingSplittingInZK");
     try {


Reply via email to