View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.util.hbck;
19  
20  import java.io.IOException;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.classification.InterfaceStability;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.fs.Path;
29  import org.apache.hadoop.hbase.HBaseConfiguration;
30  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
31  import org.apache.hadoop.hbase.util.FSUtils;
32  import org.apache.hadoop.hbase.util.HBaseFsck;
33  import org.apache.hadoop.io.MultipleIOException;
34  
35  /**
36   * This code is used to rebuild meta off line from file system data. If there
37   * are any problem detected, it will fail suggesting actions for the user to do
38   * to "fix" problems. If it succeeds, it will backup the previous hbase:meta and
39   * -ROOT- dirs and write new tables in place.
40   *
41   * This is an advanced feature, so is only exposed for use if explicitly
42   * mentioned.
43   *
44   * hbase org.apache.hadoop.hbase.util.hbck.OfflineMetaRepair ...
45   */
46  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
47  @InterfaceStability.Evolving
48  public class OfflineMetaRepair {
49    private static final Log LOG = LogFactory.getLog(OfflineMetaRepair.class.getName());
50  
51    protected static void printUsageAndExit() {
52      StringBuilder sb = new StringBuilder();
53      sb.append("Usage: OfflineMetaRepair [opts]\n").
54         append(" where [opts] are:\n").
55         append("   -details               Display full report of all regions.\n").
56         append("   -base <hdfs://>        Base Hbase Data directory.\n").
57         append("   -sidelineDir <hdfs://> HDFS path to backup existing meta and root.\n").
58         append("   -fix                   Auto fix as many problems as possible.\n").
59         append("   -fixHoles              Auto fix as region holes.");
60      System.err.println(sb.toString());
61      Runtime.getRuntime().exit(-2);
62    }
63  
64    /**
65     * Main program
66     *
67     * @param args
68     * @throws Exception
69     */
70    public static void main(String[] args) throws Exception {
71  
72      // create a fsck object
73      Configuration conf = HBaseConfiguration.create();
74      // Cover both bases, the old way of setting default fs and the new.
75      // We're supposed to run on 0.20 and 0.21 anyways.
76      FSUtils.setFsDefault(conf, FSUtils.getRootDir(conf));
77      HBaseFsck fsck = new HBaseFsck(conf);
78      boolean fixHoles = false;
79  
80      // Process command-line args.
81      for (int i = 0; i < args.length; i++) {
82        String cmd = args[i];
83        if (cmd.equals("-details")) {
84          fsck.setDisplayFullReport();
85        } else if (cmd.equals("-base")) {
86          if (i == args.length - 1) {
87            System.err.println("OfflineMetaRepair: -base needs an HDFS path.");
88            printUsageAndExit();
89          }
90          // update hbase root dir to user-specified base
91          i++;
92          FSUtils.setRootDir(conf, new Path(args[i]));
93          FSUtils.setFsDefault(conf, FSUtils.getRootDir(conf));
94        } else if (cmd.equals("-sidelineDir")) {
95          if (i == args.length - 1) {
96            System.err.println("OfflineMetaRepair: -sidelineDir needs an HDFS path.");
97            printUsageAndExit();
98          }
99          // set the hbck sideline dir to user-specified one
100         i++;
101         fsck.setSidelineDir(args[i]);
102       } else if (cmd.equals("-fixHoles")) {
103         fixHoles = true;
104       } else if (cmd.equals("-fix")) {
105         // make all fix options true
106         fixHoles = true;
107       } else {
108         String str = "Unknown command line option : " + cmd;
109         LOG.info(str);
110         System.out.println(str);
111         printUsageAndExit();
112       }
113     }
114 
115     System.out.println("OfflineMetaRepair command line options: " + StringUtils.join(args, " "));
116 
117     // Fsck doesn't shutdown and and doesn't provide a way to shutdown its
118     // threads cleanly, so we do a System.exit.
119     boolean success = false;
120     try {
121       success = fsck.rebuildMeta(fixHoles);
122     } catch (MultipleIOException mioes) {
123       for (IOException ioe : mioes.getExceptions()) {
124         LOG.error("Bailed out due to:", ioe);
125       }
126     } catch (Exception e) {
127       LOG.error("Bailed out due to: ", e);
128     } finally {
129       System.exit(success ? 0 : 1);
130     }
131   }
132 }