You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by jm...@apache.org on 2012/04/11 19:20:09 UTC

svn commit: r1324880 - in /hbase/branches/0.94/src: main/java/org/apache/hadoop/hbase/util/HBaseFsck.java test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java test/java/org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java

Author: jmhsieh
Date: Wed Apr 11 17:20:09 2012
New Revision: 1324880

URL: http://svn.apache.org/viewvc?rev=1324880&view=rev
Log:
HBASE-5599 [hbck] handle NO_VERSION_FILE and SHOULD_NOT_BE_DEPLOYED inconsistencies (fulin wang)

Modified:
    hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
    hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
    hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java

Modified: hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java?rev=1324880&r1=1324879&r2=1324880&view=diff
==============================================================================
--- hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java (original)
+++ hbase/branches/0.94/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java Wed Apr 11 17:20:09 2012
@@ -160,6 +160,7 @@ public class HBaseFsck {
   private boolean fixHdfsHoles = false; // fix fs holes?
   private boolean fixHdfsOverlaps = false; // fix fs overlaps (risky)
   private boolean fixHdfsOrphans = false; // fix fs holes (missing .regioninfo)
+  private boolean fixVersionFile = false; // fix missing hbase.version file in hdfs
 
   // limit fixes to listed tables, if empty atttempt to fix all
   private List<byte[]> tablesToFix = new ArrayList<byte[]>();
@@ -1001,6 +1002,15 @@ public class HBaseFsck {
     if (!foundVersionFile) {
       errors.reportError(ERROR_CODE.NO_VERSION_FILE,
           "Version file does not exist in root dir " + rootDir);
+      if (shouldFixVersionFile()) {
+        LOG.info("Trying to create a new " + HConstants.VERSION_FILE_NAME
+            + " file.");
+        setShouldRerun();
+        FSUtils.setVersion(fs, rootDir, conf.getInt(
+            HConstants.THREAD_WAKE_FREQUENCY, 10 * 1000), conf.getInt(
+            HConstants.VERSION_FILE_WRITE_ATTEMPTS,
+            HConstants.DEFAULT_VERSION_FILE_WRITE_ATTEMPTS));
+      }
     }
 
     // level 1:  <HBASE_DIR>/*
@@ -1351,10 +1361,14 @@ public class HBaseFsck {
           + " not deployed on any region server.");
       tryAssignmentRepair(hbi, "Trying to fix unassigned region...");
     } else if (inMeta && inHdfs && isDeployed && !shouldBeDeployed) {
-      errors.reportError(ERROR_CODE.SHOULD_NOT_BE_DEPLOYED, "UNHANDLED CASE:" +
-          " Region " + descriptiveName + " should not be deployed according " +
+      errors.reportError(ERROR_CODE.SHOULD_NOT_BE_DEPLOYED,
+          "Region " + descriptiveName + " should not be deployed according " +
           "to META, but is deployed on " + Joiner.on(", ").join(hbi.deployedOn));
-      // TODO test and handle this case.
+      if (shouldFixAssignments()) {
+        errors.print("Trying to close the region " + descriptiveName);
+        setShouldRerun();
+        HBaseFsckRepair.fixMultiAssignment(admin, hbi.metaEntry, hbi.deployedOn);
+      }
     } else if (inMeta && inHdfs && isMultiplyDeployed) {
       errors.reportError(ERROR_CODE.MULTI_DEPLOYED, "Region " + descriptiveName
           + " is listed in META on region server " + hbi.metaEntry.regionServer
@@ -2729,6 +2743,14 @@ public class HBaseFsck {
     return fixHdfsOrphans;
   }
 
+  public void setFixVersionFile(boolean shouldFix) {
+    fixVersionFile = shouldFix;
+  }
+
+  public boolean shouldFixVersionFile() {
+    return fixVersionFile;
+  }
+
   /**
    * @param mm maximum number of regions to merge into a single region.
    */
@@ -2787,9 +2809,11 @@ public class HBaseFsck {
     System.err.println("   -fixHdfsHoles     Try to fix region holes in hdfs.");
     System.err.println("   -fixHdfsOrphans   Try to fix region dirs with no .regioninfo file in hdfs");
     System.err.println("   -fixHdfsOverlaps  Try to fix region overlaps in hdfs.");
+    System.err.println("   -fixVersionFile   Try to fix missing hbase.version file in hdfs.");
     System.err.println("   -maxMerge <n>     When fixing region overlaps, allow at most <n> regions to merge. (n=" + DEFAULT_MAX_MERGE +" by default)");
     System.err.println("");
-    System.err.println("   -repair           Shortcut for -fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans -fixHdfsOverlaps");
+    System.err.println("   -repair           Shortcut for -fixAssignments -fixMeta -fixHdfsHoles " +
+        "-fixHdfsOrphans -fixHdfsOverlaps -fixVersionFile");
     System.err.println("   -repairHoles      Shortcut for -fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans");
 
     Runtime.getRuntime().exit(-2);
@@ -2852,6 +2876,8 @@ public class HBaseFsck {
         fsck.setFixHdfsOrphans(true);
       } else if (cmd.equals("-fixHdfsOverlaps")) {
         fsck.setFixHdfsOverlaps(true);
+      } else if (cmd.equals("-fixVersionFile")) {
+        fsck.setFixVersionFile(true);
       } else if (cmd.equals("-repair")) {
         // this attempts to merge overlapping hdfs regions, needs testing
         // under load
@@ -2860,6 +2886,7 @@ public class HBaseFsck {
         fsck.setFixMeta(true);
         fsck.setFixAssignments(true);
         fsck.setFixHdfsOverlaps(true);
+        fsck.setFixVersionFile(true);
       } else if (cmd.equals("-repairHoles")) {
         // this will make all missing hdfs regions available but may lose data
         fsck.setFixHdfsHoles(true);
@@ -2909,6 +2936,7 @@ public class HBaseFsck {
       fsck.setFixMeta(false);
       fsck.setFixHdfsHoles(false);
       fsck.setFixHdfsOverlaps(false);
+      fsck.setFixVersionFile(false);
       fsck.errors.resetErrors();
       code = fsck.onlineHbck();
     }

Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java?rev=1324880&r1=1324879&r2=1324880&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java (original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java Wed Apr 11 17:20:09 2012
@@ -23,6 +23,7 @@ import static org.apache.hadoop.hbase.ut
 import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.assertNoErrors;
 import static org.apache.hadoop.hbase.util.hbck.HbckTestingUtil.doFsck;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
@@ -36,7 +37,6 @@ import java.util.Map.Entry;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.ClusterStatus;
@@ -45,6 +45,7 @@ import org.apache.hadoop.hbase.HColumnDe
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.MiniHBaseCluster;
 import org.apache.hadoop.hbase.MediumTests;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.client.Delete;
@@ -55,9 +56,15 @@ import org.apache.hadoop.hbase.client.Pu
 import org.apache.hadoop.hbase.client.Result;
 import org.apache.hadoop.hbase.client.ResultScanner;
 import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.executor.RegionTransitionData;
+import org.apache.hadoop.hbase.executor.EventHandler.EventType;
 import org.apache.hadoop.hbase.ipc.HRegionInterface;
 import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
+import org.apache.hadoop.hbase.util.HBaseFsck;
 import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter.ERROR_CODE;
+import org.apache.hadoop.hbase.zookeeper.ZKAssign;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
 import org.apache.zookeeper.KeeperException;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -73,6 +80,7 @@ public class TestHBaseFsck {
   private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
   private final static Configuration conf = TEST_UTIL.getConfiguration();
   private final static byte[] FAM = Bytes.toBytes("fam");
+  private final static int REGION_ONLINE_TIMEOUT = 300;
 
   // for the instance, reset every test run
   private HTable tbl;
@@ -851,8 +859,100 @@ public class TestHBaseFsck {
     fail("Should have failed with IOException");
   }
 
+  /**
+   * when the hbase.version file missing, It is fix the fault.
+   */
+  @Test
+  public void testNoVersionFile() throws Exception {
+    // delete the hbase.version file
+    Path rootDir = new Path(conf.get(HConstants.HBASE_DIR));
+    FileSystem fs = rootDir.getFileSystem(conf);
+    Path versionFile = new Path(rootDir, HConstants.VERSION_FILE_NAME);
+    fs.delete(versionFile, true);
+
+    // test
+    HBaseFsck hbck = doFsck(conf, false);
+    assertErrors(hbck, new ERROR_CODE[] { ERROR_CODE.NO_VERSION_FILE });
+    // fix hbase.version missing
+    doFsck(conf, true);
+
+    // no version file fixed
+    assertNoErrors(doFsck(conf, false));
+  }
+
+  /**
+   * the region is not deployed when the table is disabled.
+   */
+  @Test
+  public void testRegionShouldNotDeployed() throws Exception {
+    String table = "tableRegionShouldNotDeployed";
+    try {
+      LOG.info("Starting testRegionShouldNotDeployed.");
+      MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
+      assertTrue(cluster.waitForActiveAndReadyMaster());
+
+      // Create a ZKW to use in the test
+      ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
+
+      FileSystem filesystem = FileSystem.get(conf);
+      Path rootdir = filesystem.makeQualified(new Path(conf
+          .get(HConstants.HBASE_DIR)));
+
+      byte[][] SPLIT_KEYS = new byte[][] { new byte[0], Bytes.toBytes("aaa"),
+          Bytes.toBytes("bbb"), Bytes.toBytes("ccc"), Bytes.toBytes("ddd") };
+      HTableDescriptor htdDisabled = new HTableDescriptor(Bytes.toBytes(table));
+      htdDisabled.addFamily(new HColumnDescriptor(FAM));
+
+      // Write the .tableinfo
+      FSTableDescriptors
+          .createTableDescriptor(filesystem, rootdir, htdDisabled);
+      List<HRegionInfo> disabledRegions = TEST_UTIL.createMultiRegionsInMeta(
+          TEST_UTIL.getConfiguration(), htdDisabled, SPLIT_KEYS);
+
+      // Let's just assign everything to first RS
+      HRegionServer hrs = cluster.getRegionServer(0);
+      ServerName serverName = hrs.getServerName();
+
+      // create region files.
+      TEST_UTIL.getHBaseAdmin().disableTable(table);
+      TEST_UTIL.getHBaseAdmin().enableTable(table);
+
+      // Region of disable table was opened on RS
+      TEST_UTIL.getHBaseAdmin().disableTable(table);
+      HRegionInfo region = disabledRegions.remove(0);
+      ZKAssign.createNodeOffline(zkw, region, serverName);
+      hrs.openRegion(region);
+
+      int iTimes = 0;
+      while (true) {
+        RegionTransitionData rtd = ZKAssign.getData(zkw,
+            region.getEncodedName());
+        if (rtd != null && rtd.getEventType() == EventType.RS_ZK_REGION_OPENED) {
+          break;
+        }
+        Thread.sleep(100);
+        iTimes++;
+        if (iTimes >= REGION_ONLINE_TIMEOUT) {
+          break;
+        }
+      }
+      assertTrue(iTimes < REGION_ONLINE_TIMEOUT);
+
+      HBaseFsck hbck = doFsck(conf, false);
+      assertErrors(hbck, new ERROR_CODE[] { ERROR_CODE.SHOULD_NOT_BE_DEPLOYED });
+
+      // fix this fault
+      doFsck(conf, true);
+
+      // check result
+      assertNoErrors(doFsck(conf, false));
+    } finally {
+      TEST_UTIL.getHBaseAdmin().enableTable(table);
+      deleteTable(table);
+    }
+  }
+
   @org.junit.Rule
   public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
     new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
 }
-

Modified: hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java?rev=1324880&r1=1324879&r2=1324880&view=diff
==============================================================================
--- hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java (original)
+++ hbase/branches/0.94/src/test/java/org/apache/hadoop/hbase/util/hbck/HbckTestingUtil.java Wed Apr 11 17:20:09 2012
@@ -29,12 +29,12 @@ import org.apache.hadoop.hbase.util.HBas
 
 public class HbckTestingUtil {
   public static HBaseFsck doFsck(Configuration conf, boolean fix) throws Exception {
-    return doFsck(conf, fix, fix, fix, fix,fix);
+    return doFsck(conf, fix, fix, fix, fix,fix, fix);
   }
 
   public static HBaseFsck doFsck(Configuration conf, boolean fixAssignments,
       boolean fixMeta, boolean fixHdfsHoles, boolean fixHdfsOverlaps,
-      boolean fixHdfsOrphans) throws Exception {
+      boolean fixHdfsOrphans, boolean fixVersionFile) throws Exception {
     HBaseFsck fsck = new HBaseFsck(conf);
     fsck.connect();
     fsck.setDisplayFullReport(); // i.e. -details
@@ -44,6 +44,7 @@ public class HbckTestingUtil {
     fsck.setFixHdfsHoles(fixHdfsHoles);
     fsck.setFixHdfsOverlaps(fixHdfsOverlaps);
     fsck.setFixHdfsOrphans(fixHdfsOrphans);
+    fsck.setFixVersionFile(fixVersionFile);
     fsck.onlineHbck();
     return fsck;
   }