hadoop-common-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r614413 - in /lucene/hadoop/trunk/src/contrib/hbase: ./ bin/ src/java/org/apache/hadoop/hbase/ src/java/org/apache/hadoop/hbase/util/ src/test/org/apache/hadoop/hbase/util/
Date Wed, 23 Jan 2008 03:24:33 GMT
Author: jimk
Date: Tue Jan 22 19:24:32 2008
New Revision: 614413

URL: http://svn.apache.org/viewvc?rev=614413&view=rev
Log:
HADOOP-2668 Documentation and improved logging so fact that hbase now requires migration comes
as less of a surprise

Modified:
    lucene/hadoop/trunk/src/contrib/hbase/CHANGES.txt
    lucene/hadoop/trunk/src/contrib/hbase/bin/hbase
    lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMaster.java
    lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java
    lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/package.html
    lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/FSUtils.java
    lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/Migrate.java
    lucene/hadoop/trunk/src/contrib/hbase/src/test/org/apache/hadoop/hbase/util/TestMigrate.java

Modified: lucene/hadoop/trunk/src/contrib/hbase/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/CHANGES.txt?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/CHANGES.txt (original)
+++ lucene/hadoop/trunk/src/contrib/hbase/CHANGES.txt Tue Jan 22 19:24:32 2008
@@ -143,6 +143,8 @@
    HADOOP-2584 Web UI displays an IOException instead of the Tables
    HADOOP-2650 Remove Writables.clone and use WritableUtils.clone from
                hadoop instead
+   HADOOP-2668 Documentation and improved logging so fact that hbase now
+               requires migration comes as less of a surprise
    
   IMPROVEMENTS
    HADOOP-2401 Add convenience put method that takes writable

Modified: lucene/hadoop/trunk/src/contrib/hbase/bin/hbase
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/bin/hbase?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/bin/hbase (original)
+++ lucene/hadoop/trunk/src/contrib/hbase/bin/hbase Tue Jan 22 19:24:32 2008
@@ -63,6 +63,7 @@
   echo "  regionserver     run an Hbase HRegionServer node" 
   echo "  rest             run an Hbase REST server" 
   echo "  thrift           run an Hbase Thrift server" 
+  echo "  migrate          upgrade an hbase.rootdir"
   echo " or"
   echo "  CLASSNAME        run the class named CLASSNAME"
   echo "Most commands print help when invoked w/o parameters."
@@ -219,6 +220,8 @@
   CLASS='org.apache.hadoop.hbase.rest.Dispatcher'
 elif [ "$COMMAND" = "thrift" ] ; then
   CLASS='org.apache.hadoop.hbase.thrift.ThriftServer'
+elif [ "$COMMAND" = "migrate" ] ; then
+  CLASS='org.apache.hadoop.hbase.util.Migrate'
 else
   CLASS=$COMMAND
 fi

Modified: lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMaster.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMaster.java?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMaster.java (original)
+++ lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HMaster.java Tue
Jan 22 19:24:32 2008
@@ -891,8 +891,8 @@
         fs.mkdirs(rootdir);
         FSUtils.setVersion(fs, rootdir);
       } else if (!FSUtils.checkVersion(fs, rootdir)) {
-        throw new IOException(
-            "file system not correct version. Run hbase.util.Migrate");
+        throw new IOException("File system needs upgrade. Run " +
+          "the '${HBASE_HOME}/bin/hbase migrate' script");
       }
 
       if (!fs.exists(rootRegionDir)) {

Modified: lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java (original)
+++ lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/HRegion.java Tue
Jan 22 19:24:32 2008
@@ -1871,7 +1871,7 @@
    * @param info HRegionInfo for the region
    * @return qualified path of region directory
    */
-  static Path getRegionDir(final Path rootdir, final HRegionInfo info) {
+  public static Path getRegionDir(final Path rootdir, final HRegionInfo info) {
     return new Path(
         HTableDescriptor.getTableDir(rootdir, info.getTableDesc().getName()),
         info.getEncodedName()

Modified: lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/package.html
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/package.html?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/package.html (original)
+++ lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/package.html Tue
Jan 22 19:24:32 2008
@@ -2,13 +2,13 @@
 <html>
 <head />
 <body bgcolor="white">
-Provides HBase, the <a href="http://lucene.apache.org/hadoop">Hadoop</a>
+Provides Hbase, the <a href="http://lucene.apache.org/hadoop">Hadoop</a>
 simple database.
 
 <h2><a name="requirements">Requirements</a></h2>
 <ul>
 <li>Java 1.5.x, preferably from <a href="http://www.java.com/en/download/">Sun</a>.</li>
-<li>HBase runs on top of <a href="http://lucene.apache.org/hadoop">Hadoop</a>.
 Hadoop has its own set of
+<li>Hbase runs on top of <a href="http://lucene.apache.org/hadoop">Hadoop</a>.
 Hadoop has its own set of
 <a href="http://lucene.apache.org/hadoop/api/overview-summary.html#overview_description">
 requirements and instructions</a>.  Make sure to set 
 <code>JAVA_HOME</code> to the root of your Java installation when configuring
Hadoop.
@@ -17,13 +17,19 @@
 
 <h2><a name="getting_started" >Getting Started</a></h2>
 <p>
+What follows presumes you are installing hbase for the first time. If upgrading your
+hbase instance, see <a href="#upgrading">Upgrading</a>.
+</p>
+<p>
 Start by defining the following directory variables for your convenience:
 </p>
+<p>
 <ul>
 <li><code>${HADOOP_HOME}</code>: The root directory of your Hadoop installation.</li>
-<li><code>${HBASE_HOME}</code>: The HBase root, located at 
+<li><code>${HBASE_HOME}</code>: The Hbase root, located at 
 <code>${HADOOP_HOME}/src/contrib/hbase</code>.</li>
 </ul>
+</p>
 <p>
 If you are running a standalone operation, proceed to <a href=#runandconfirm>Running

 and Confirming Your Installation</a>.  If you are running a distributed operation,
continue below.
@@ -34,7 +40,7 @@
 Make sure you have followed
 <a href="http://lucene.apache.org/hadoop/api/overview-summary.html#overview_description">
 Hadoop's instructions</a> for running a distributed operation.  
-Configuring HBase for a distributed operation requires modification of the following two

+Configuring Hbase for a distributed operation requires modification of the following two

 files: <code>${HBASE_HOME}/conf/hbase-site.xml</code> and 
 <code>${HBASE_HOME}/conf/regionservers</code>.  
 </p>
@@ -44,7 +50,7 @@
 should never be modified).  At a minimum the <code>hbase.master</code> property
should be redefined 
 in <code>hbase-site.xml</code> to define the <code>host:port</code>
pair on which to run the 
 HMaster (<a href="http://wiki.apache.org/lucene-hadoop/Hbase/HbaseArchitecture">read
about the 
-HBase master, regionservers, etc</a>):
+Hbase master, regionservers, etc</a>):
 </p>
 <pre>
 &lt;configuration&gt;
@@ -52,7 +58,7 @@
   &lt;property&gt;
     &lt;name&gt;hbase.master&lt;/name&gt;
     &lt;value&gt;[YOUR_HOST]:[PORT]&lt;/value&gt;
-    &lt;description&gt;The host and port that the HBase master runs at.
+    &lt;description&gt;The host and port that the Hbase master runs at.
     &lt;/description&gt;
   &lt;/property&gt;
 
@@ -65,8 +71,8 @@
 </p>
 <h3><a name="additional" >Additional Notes on Distributed Operation</a></h3>
 <ul>
-<li>Hadoop and HBase must be set up on each host you plan to use.</li>
-<li>Additional (optional) HBase-specific variables such as HBASE_HEAPSIZE and HBASE_CLASSPATH

+<li>Hadoop and Hbase must be set up on each host you plan to use.</li>
+<li>Additional (optional) Hbase-specific variables such as HBASE_HEAPSIZE and HBASE_CLASSPATH

 can be set in <code>${HBASE_HOME}/conf/hbase-env.sh</code>.</li>
 </ul>
 
@@ -74,42 +80,49 @@
 <p>If you are running in standalone, non-distributed mode, hbase by default uses
 the local filesystem.</p>
 <p>If you are running a distributed cluster you will need to start the Hadoop DFS daemons

-before starting HBase and stop the daemons after HBase has shut down.  Start and 
+before starting Hbase and stop the daemons after Hbase has shut down.  Start and 
 stop the Hadoop DFS daemons as per the Hadoop 
-<a href="http://lucene.apache.org/hadoop/api/overview-summary.html">instructions</a>.
HBase
+<a href="http://lucene.apache.org/hadoop/api/overview-summary.html">instructions</a>.
Hbase
 does not normally use the mapreduce daemons.  These do not need to be started.</p>
 
-<p>Start HBase with the following command:
+<p>Start Hbase with the following command:
 </p>
 <pre>
 ${HBASE_HOME}/bin/start-hbase.sh
 </pre>
 <p>
-Once HBase has started, enter <code>${HBASE_HOME}/bin/hbase shell</code> to obtain
a 
-shell against HBase from which you can execute HBase commands.  In the HBase shell, type

-<code>help;</code> to see a list of supported commands.  Note that all commands
in the HBase 
+Once Hbase has started, enter <code>${HBASE_HOME}/bin/hbase shell</code> to obtain
a 
+shell against Hbase from which you can execute Hbase commands.  In the Hbase shell, type

+<code>help;</code> to see a list of supported commands.  Note that all commands
in the Hbase 
 shell must end with <code>;</code>.  Test your installation by creating, viewing,
and dropping 
 a table, as per the help instructions.  Be patient with the <code>create</code>
and 
 <code>drop</code> operations as they may each take 10 seconds or more.  To stop
hbase, exit the 
-HBase shell and enter:
+Hbase shell and enter:
 </p>
 <pre>
 ${HBASE_HOME}/bin/stop-hbase.sh
 </pre>
 <p>
-If you are running a distributed operation, be sure to wait until HBase has shut down completely

+If you are running a distributed operation, be sure to wait until Hbase has shut down completely

 before stopping the Hadoop daemons.
 </p>
 <p>
 The default location for logs is <code>${HADOOP_HOME}/logs</code>.
 </p>
-<p>HBase also puts up a UI listing vital attributes.  By default its deployed on the
master host
+<p>Hbase also puts up a UI listing vital attributes.  By default its deployed on the
master host
 at port 60010.</p>
 
+<h2><a name="upgrading" >Upgrading</a></h2>
+<p>After installing the new hbase, before starting your cluster, run the
+<code>${HBASE_DIR}/bin/hbase migrate</code> migration script. It will make any
+adjustments to the filesystem data under <code>hbase.rootdir</code> necessary
to run
+the hbase version.
+</p>
+
 <h2><a name="related" >Related Documentation</a></h2>
 <ul>
-  <li><a href="http://wiki.apache.org/lucene-hadoop/Hbase">HBase Home Page</a>
-  <li><a href="http://wiki.apache.org/lucene-hadoop/Hbase/HbaseArchitecture">HBase
Architecture</a>
+  <li><a href="http://wiki.apache.org/lucene-hadoop/Hbase">Hbase Home Page</a>
+  <li><a href="http://wiki.apache.org/lucene-hadoop/Hbase/HbaseArchitecture">Hbase
Architecture</a>
 </ul>
 
 </body>

Modified: lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/FSUtils.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/FSUtils.java?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/FSUtils.java
(original)
+++ lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/FSUtils.java
Tue Jan 22 19:24:32 2008
@@ -65,7 +65,7 @@
     
     try {
       if (!available) {
-        LOG.info("Failed file system available test. Thread: " +
+        LOG.fatal("File system is not available.. Thread: " +
             Thread.currentThread().getName() + ": " + exception);
         fs.close();
       }

Modified: lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/Migrate.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/Migrate.java?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/Migrate.java
(original)
+++ lucene/hadoop/trunk/src/contrib/hbase/src/java/org/apache/hadoop/hbase/util/Migrate.java
Tue Jan 22 19:24:32 2008
@@ -21,6 +21,7 @@
 package org.apache.hadoop.hbase.util;
 
 import java.io.BufferedReader;
+import java.io.FileNotFoundException;
 import java.io.InputStreamReader;
 import java.io.IOException;
 
@@ -32,13 +33,9 @@
 import java.util.TreeMap;
 
 import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.OptionBuilder;
 import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -76,8 +73,9 @@
 
   private final HBaseConfiguration conf;
 
-  /** Action to take when an extra file is found */
-  private static enum EXTRA_FILES  {
+  /** Action to take when an extra file or unrecoverd log file is found */
+  private static String ACTIONS = "abort|ignore|delete|prompt";
+  private static enum ACTION  {
     /** Stop conversion */
     ABORT,
     /** print a warning message, but otherwise ignore */
@@ -88,18 +86,21 @@
     PROMPT
   }
   
-  private static final Map<String, EXTRA_FILES> options =
-    new HashMap<String, EXTRA_FILES>();
+  private static final Map<String, ACTION> options =
+    new HashMap<String, ACTION>();
   
   static {
-   options.put("abort", EXTRA_FILES.ABORT);
-   options.put("ignore", EXTRA_FILES.IGNORE);
-   options.put("delete", EXTRA_FILES.DELETE);
-   options.put("prompt", EXTRA_FILES.PROMPT);
+   options.put("abort", ACTION.ABORT);
+   options.put("ignore", ACTION.IGNORE);
+   options.put("delete", ACTION.DELETE);
+   options.put("prompt", ACTION.PROMPT);
   }
-  
-  private EXTRA_FILES logFiles = EXTRA_FILES.ABORT;
-  private EXTRA_FILES otherFiles = EXTRA_FILES.IGNORE;
+
+  private boolean readOnly = false;
+  private boolean migrationNeeded = false;
+  private boolean newRootRegion = false;
+  private ACTION logFiles = ACTION.IGNORE;
+  private ACTION otherFiles = ACTION.IGNORE;
 
   private BufferedReader reader = null;
   
@@ -120,56 +121,101 @@
   }
   
   /** {@inheritDoc} */
-  public int run(String[] args) throws Exception {
-    parseArgs(args);
-    
+  public int run(String[] args) {
+    if (parseArgs(args) != 0) {
+      return -1;
+    }
+
     try {
-      HBaseAdmin admin = new HBaseAdmin(conf);
-      if (admin.isMasterRunning()) {
-        throw new IllegalStateException(
-        "HBase cluster must be off-line while being upgraded");
-      }
-    } catch (MasterNotRunningException e) {
-      // ignore
-    }
-    FileSystem fs = FileSystem.get(conf);               // get DFS handle
-    Path rootdir = fs.makeQualified(new Path(          // get path for instance
-        conf.get(HConstants.HBASE_DIR, HConstants.DEFAULT_HBASE_DIR)));
+      FileSystem fs = FileSystem.get(conf);               // get DFS handle
 
-    // See if there is a file system version file
-    
-    if (FSUtils.checkVersion(fs, rootdir)) {
-      LOG.info("file system is at current level, no upgrade necessary");
-      return 0;
-    }
-    
-    // check for "extra" files and for old upgradable regions
+      LOG.info("Verifying that file system is available...");
+      if (!FSUtils.isFileSystemAvailable(fs)) {
+        throw new IOException(
+            "Filesystem must be available for upgrade to run.");
+      }
+
+      LOG.info("Verifying that HBase is not running...");
+      try {
+        HBaseAdmin admin = new HBaseAdmin(conf);
+        if (admin.isMasterRunning()) {
+          throw new IllegalStateException(
+            "HBase cluster must be off-line during upgrade.");
+        }
+      } catch (MasterNotRunningException e) {
+        // ignore
+      }
 
-    extraFiles(fs, rootdir);
+      LOG.info("Starting upgrade" + (readOnly ? " check" : ""));
 
-    // find root region
+      Path rootdir = fs.makeQualified(new Path(           // get HBase root dir
+          conf.get(HConstants.HBASE_DIR, HConstants.DEFAULT_HBASE_DIR)));
 
-    Path rootRegion = new Path(rootdir, 
-        OLD_PREFIX + HRegionInfo.rootRegionInfo.getEncodedName());
+      if (!fs.exists(rootdir)) {
+        throw new FileNotFoundException("HBase root directory " +
+            rootdir.toString() + " does not exist.");
+      }
 
-    if (!fs.exists(rootRegion)) {
-      throw new IOException("cannot find root region " + rootRegion.toString());
-    }
+      // See if there is a file system version file
 
-    processRegionDir(fs, rootdir, HConstants.ROOT_TABLE_NAME, rootRegion);
-    scanRootRegion(fs, rootdir);
+      if (FSUtils.checkVersion(fs, rootdir)) {
+        LOG.info("No upgrade necessary.");
+        return 0;
+      }
 
-    // scan for left over regions
+      // check to see if new root region dir exists
 
-    extraRegions(fs, rootdir);
-    
-    // set file system version
-    
-    FSUtils.setVersion(fs, rootdir);
+      checkNewRootRegionDirExists(fs, rootdir);
 
-    return 0;
+      // check for "extra" files and for old upgradable regions
+
+      extraFiles(fs, rootdir);
+
+      if (!newRootRegion) {
+        // find root region
+
+        Path rootRegion = new Path(rootdir, 
+            OLD_PREFIX + HRegionInfo.rootRegionInfo.getEncodedName());
+
+        if (!fs.exists(rootRegion)) {
+          throw new IOException("Cannot find root region " +
+              rootRegion.toString());
+        } else if (readOnly) {
+          migrationNeeded = true;
+        } else {
+          migrateRegionDir(fs, rootdir, HConstants.ROOT_TABLE_NAME, rootRegion);
+          scanRootRegion(fs, rootdir);
+
+          // scan for left over regions
+
+          extraRegions(fs, rootdir);
+        }
+      }
+
+      if (!readOnly) {
+        // set file system version
+        LOG.info("Setting file system version.");
+        FSUtils.setVersion(fs, rootdir);
+        LOG.info("Upgrade successful.");
+      } else if (migrationNeeded) {
+        LOG.info("Upgrade needed.");
+      }
+      return 0;
+    } catch (Exception e) {
+      LOG.fatal("Upgrade" +  (readOnly ? " check" : "") + " failed", e);
+      return -1;
+    }
+  }
+
+  private void checkNewRootRegionDirExists(FileSystem fs, Path rootdir)
+  throws IOException {
+    Path rootRegionDir =
+      HRegion.getRegionDir(rootdir, HRegionInfo.rootRegionInfo);
+    newRootRegion = fs.exists(rootRegionDir);
+    migrationNeeded = !newRootRegion;
   }
   
+  // Check for files that should not be there or should be migrated
   private void extraFiles(FileSystem fs, Path rootdir) throws IOException {
     FileStatus[] stats = fs.listStatus(rootdir);
     if (stats == null || stats.length == 0) {
@@ -178,44 +224,52 @@
     }
     for (int i = 0; i < stats.length; i++) {
       String name = stats[i].getPath().getName();
-      if (!name.startsWith(OLD_PREFIX)) {
-        if (name.startsWith("log_")) {
-          String message = "unrecovered region server log file " + name; 
-          extraFile(logFiles, message, fs, stats[i].getPath());
+      if (name.startsWith(OLD_PREFIX)) {
+        if (!newRootRegion) {
+          // We need to migrate if the new root region directory doesn't exist
+          migrationNeeded = true;
+          String regionName = name.substring(OLD_PREFIX.length());
+          try {
+            Integer.parseInt(regionName);
+
+          } catch (NumberFormatException e) {
+            extraFile(otherFiles, "Old region format can not be upgraded: " +
+                name, fs, stats[i].getPath());
+          }
         } else {
-          String message = "unrecognized file " + name;
-          extraFile(otherFiles, message, fs, stats[i].getPath());
+          // Since the new root region directory exists, we assume that this
+          // directory is not necessary
+          extraFile(otherFiles, "Old region directory found: " + name, fs,
+              stats[i].getPath());
         }
       } else {
-        String regionName = name.substring(OLD_PREFIX.length());
-        try {
-          Integer.parseInt(regionName);
-          
-        } catch (NumberFormatException e) {
-          extraFile(otherFiles, "old region format can not be converted: " +
-              name, fs, stats[i].getPath());
+        // File name does not start with "hregion_"
+        if (name.startsWith("log_")) {
+          String message = "Unrecovered region server log file " + name +
+            " this file can be recovered by the master when it starts."; 
+          extraFile(logFiles, message, fs, stats[i].getPath());
+        } else if (!newRootRegion) {
+          // new root region directory does not exist. This is an extra file
+          String message = "Unrecognized file " + name;
+          extraFile(otherFiles, message, fs, stats[i].getPath());
         }
       }
     }
   }
 
-  private void extraFile(EXTRA_FILES action, String message, FileSystem fs,
+  private void extraFile(ACTION action, String message, FileSystem fs,
       Path p) throws IOException {
     
-    if (action == EXTRA_FILES.ABORT) {
+    if (action == ACTION.ABORT) {
       throw new IOException(message + " aborting");
-
-    } else if (action == EXTRA_FILES.IGNORE) {
+    } else if (action == ACTION.IGNORE) {
       LOG.info(message + " ignoring");
-
-    } else if (action == EXTRA_FILES.DELETE) {
+    } else if (action == ACTION.DELETE) {
       LOG.info(message + " deleting");
       fs.delete(p);
-
     } else {
-      // logFiles == EXTRA_FILES.PROMPT
+      // ACTION.PROMPT
       String response = prompt(message + " delete? [y/n]");
-
       if (response.startsWith("Y") || response.startsWith("y")) {
         LOG.info(message + " deleting");
         fs.delete(p);
@@ -223,7 +277,7 @@
     }
   }
   
-  private void processRegionDir(FileSystem fs, Path rootdir, Text tableName,
+  private void migrateRegionDir(FileSystem fs, Path rootdir, Text tableName,
       Path oldPath) throws IOException {
 
     // Create directory where table will live
@@ -300,7 +354,7 @@
             // First move the meta region to where it should be and rename
             // subdirectories as necessary
 
-            processRegionDir(fs, rootdir, HConstants.META_TABLE_NAME,
+            migrateRegionDir(fs, rootdir, HConstants.META_TABLE_NAME,
                 new Path(rootdir, OLD_PREFIX + info.getEncodedName()));
 
             // Now scan and process the meta table
@@ -348,7 +402,7 @@
           // Move the region to where it should be and rename
           // subdirectories as necessary
 
-          processRegionDir(fs, rootdir, region.getTableDesc().getName(),
+          migrateRegionDir(fs, rootdir, region.getTableDesc().getName(),
               new Path(rootdir, OLD_PREFIX + region.getEncodedName()));
 
           results.clear();
@@ -376,11 +430,11 @@
         String message;
         if (references.contains(encodedName)) {
           message =
-            "region not in meta table but other regions reference it " + name;
+            "Region not in meta table but other regions reference it " + name;
 
         } else {
           message = 
-            "region not in meta table and no other regions reference it " + name;
+            "Region not in meta table and no other regions reference it " + name;
         }
         extraFile(otherFiles, message, fs, stats[i].getPath());
       }
@@ -388,15 +442,15 @@
   }
   
   @SuppressWarnings("static-access")
-  private void parseArgs(String[] args) {
+  private int parseArgs(String[] args) {
     Options opts = new Options();
-    Option logFiles = OptionBuilder.withArgName("abort|ignore|delete|prompt")
+    Option logFiles = OptionBuilder.withArgName(ACTIONS)
     .hasArg()
     .withDescription(
         "disposition of unrecovered region server logs: {abort|ignore|delete|prompt}")
     .create("logfiles");
 
-    Option extraFiles = OptionBuilder.withArgName("abort|ignore|delete|prompt")
+    Option extraFiles = OptionBuilder.withArgName(ACTIONS)
     .hasArg()
     .withDescription("disposition of 'extra' files: {abort|ignore|delete|prompt}")
     .create("extrafiles");
@@ -404,21 +458,62 @@
     opts.addOption(logFiles);
     opts.addOption(extraFiles);
     
-    CommandLineParser parser = new GnuParser();
-    try {
-      CommandLine commandLine = parser.parse(opts, args, true);
-      if (commandLine.hasOption("log-files")) {
-        this.logFiles = options.get(commandLine.getOptionValue("log-files"));
+    GenericOptionsParser parser =
+      new GenericOptionsParser(this.getConf(), opts, args);
+    
+    String[] remainingArgs = parser.getRemainingArgs();
+    if (remainingArgs.length != 1) {
+      usage();
+      return -1;
+    }
+    if (remainingArgs[0].compareTo("check") == 0) {
+      this.readOnly = true;
+    } else if (remainingArgs[0].compareTo("upgrade") != 0) {
+      usage();
+      return -1;
+    }
+
+    if (readOnly) {
+      this.logFiles = ACTION.IGNORE;
+      this.otherFiles = ACTION.IGNORE;
+
+    } else {
+      CommandLine commandLine = parser.getCommandLine();
+
+      ACTION action = null;
+      if (commandLine.hasOption("logfiles")) {
+        action = options.get(commandLine.getOptionValue("logfiles"));
+        if (action == null) {
+          usage();
+          return -1;
+        }
+        this.logFiles = action;
       }
-      if (commandLine.hasOption("extra-files")) {
-        this.otherFiles = options.get(commandLine.getOptionValue("extra-files"));
+      if (commandLine.hasOption("extrafiles")) {
+        action = options.get(commandLine.getOptionValue("extrafiles"));
+        if (action == null) {
+          usage();
+          return -1;
+        }
+        this.otherFiles = action;
       }
-    } catch (ParseException e) {
-      LOG.error("options parsing failed", e);
-      
-      HelpFormatter formatter = new HelpFormatter();
-      formatter.printHelp("options are: ", opts);
     }
+    return 0;
+  }
+  
+  private void usage() {
+    System.err.println("Usage: bin/hbase migrate { check | upgrade } [options]\n");
+    System.err.println("  check                            perform upgrade checks only.");
+    System.err.println("  upgrade                          perform upgrade checks and modify
hbase.\n");
+    System.err.println("  Options are:");
+    System.err.println("    -logfiles={abort|ignore|delete|prompt}");
+    System.err.println("                                   action to take when unrecovered
region");
+    System.err.println("                                   server log files are found.\n");
+    System.err.println("    -extrafiles={abort|ignore|delete|prompt}");
+    System.err.println("                                   action to take if \"extra\" files
are found.\n");
+    System.err.println("    -conf <configuration file>     specify an application configuration
file");
+    System.err.println("    -D <property=value>            use value for given property");
+    System.err.println("    -fs <local|namenode:port>      specify a namenode");
   }
   
   private synchronized String prompt(String prompt) {
@@ -441,13 +536,9 @@
    * @param args command line arguments
    */
   public static void main(String[] args) {
-    Tool t = new Migrate();
-    GenericOptionsParser hadoopOpts =
-      new GenericOptionsParser(t.getConf(), args);
-
     int status = 0;
     try {
-      status = ToolRunner.run(t, hadoopOpts.getRemainingArgs());
+      status = ToolRunner.run(new Migrate(), args);
     } catch (Exception e) {
       LOG.error("exiting due to error", e);
       status = -1;

Modified: lucene/hadoop/trunk/src/contrib/hbase/src/test/org/apache/hadoop/hbase/util/TestMigrate.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/contrib/hbase/src/test/org/apache/hadoop/hbase/util/TestMigrate.java?rev=614413&r1=614412&r2=614413&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/contrib/hbase/src/test/org/apache/hadoop/hbase/util/TestMigrate.java
(original)
+++ lucene/hadoop/trunk/src/contrib/hbase/src/test/org/apache/hadoop/hbase/util/TestMigrate.java
Tue Jan 22 19:24:32 2008
@@ -111,10 +111,30 @@
       listPaths(dfs, root, root.toString().length() + 1);
       
       Migrate u = new Migrate(conf);
-      u.run((String[]) null);
+      u.run(new String[] {"check"});
 
       listPaths(dfs, root, root.toString().length() + 1);
       
+      u = new Migrate(conf);
+      u.run(new String[] {"upgrade"});
+
+      listPaths(dfs, root, root.toString().length() + 1);
+      
+      // Remove version file and try again
+      
+      dfs.delete(new Path(root, HConstants.VERSION_FILE_NAME));
+      u = new Migrate(conf);
+      u.run(new String[] {"upgrade"});
+
+      listPaths(dfs, root, root.toString().length() + 1);
+      
+      // Try again. No upgrade should be necessary
+      
+      u = new Migrate(conf);
+      u.run(new String[] {"check"});
+      u = new Migrate(conf);
+      u.run(new String[] {"upgrade"});
+
     } catch (Exception e) {
       e.printStackTrace();
     } finally {



Mime
View raw message