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.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.HBaseConfiguration;
26  import org.apache.hadoop.hbase.HConstants;
27  import org.apache.hadoop.hbase.util.HBaseFsck;
28  import org.apache.hadoop.io.MultipleIOException;
29  
30  /**
31   * This code is used to rebuild meta off line from file system data. If there
32   * are any problem detected, it will fail suggesting actions for the user to do
33   * to "fix" problems. If it succeeds, it will backup the previous .META. and
34   * -ROOT- dirs and write new tables in place.
35   * 
36   * This is an advanced feature, so is only exposed for use if explicitly
37   * mentioned.
38   * 
39   * hbase org.apache.hadoop.hbase.util.hbck.OfflineMetaRepair ...
40   */
41  public class OfflineMetaRepair {
42    private static final Log LOG = LogFactory.getLog(OfflineMetaRepair.class.getName());
43  
44    protected static void printUsageAndExit() {
45      StringBuilder sb = new StringBuilder();
46      sb.append("Usage: OfflineMetaRepair [opts]\n").
47         append(" where [opts] are:\n").
48         append("   -details               Display full report of all regions.\n").
49         append("   -base <hdfs://>        Base Hbase Data directory.\n").
50         append("   -sidelineDir <hdfs://> HDFS path to backup existing meta and root.\n").
51         append("   -fix                   Auto fix as many problems as possible.\n").
52         append("   -fixHoles              Auto fix as region holes.");
53      System.err.println(sb.toString());
54      Runtime.getRuntime().exit(-2);
55    }
56  
57    /**
58     * Main program
59     * 
60     * @param args
61     * @throws Exception
62     */
63    public static void main(String[] args) throws Exception {
64  
65      // create a fsck object
66      Configuration conf = HBaseConfiguration.create();
67      // Cover both bases, the old way of setting default fs and the new.
68      // We're supposed to run on 0.20 and 0.21 anyways.
69      conf.set("fs.defaultFS", conf.get(HConstants.HBASE_DIR));
70      conf.set("fs.default.name", conf.get(HConstants.HBASE_DIR));
71      HBaseFsck fsck = new HBaseFsck(conf);
72      boolean fixHoles = false;
73  
74      // Process command-line args.
75      for (int i = 0; i < args.length; i++) {
76        String cmd = args[i];
77        if (cmd.equals("-details")) {
78          fsck.setDisplayFullReport();
79        } else if (cmd.equals("-base")) {
80          if (i == args.length - 1) {
81            System.err.println("OfflineMetaRepair: -base needs an HDFS path.");
82            printUsageAndExit();
83          }
84          // update hbase root dir to user-specified base
85          i++;
86          String path = args[i];
87          conf.set(HConstants.HBASE_DIR, path);
88          conf.set("fs.defaultFS", conf.get(HConstants.HBASE_DIR));
89          conf.set("fs.default.name", conf.get(HConstants.HBASE_DIR));
90        } else if (cmd.equals("-sidelineDir")) {
91          if (i == args.length - 1) {
92            System.err.println("OfflineMetaRepair: -sidelineDir needs an HDFS path.");
93            printUsageAndExit();
94          }
95          // set the hbck sideline dir to user-specified one
96          i++;
97          fsck.setSidelineDir(args[i]);
98        } else if (cmd.equals("-fixHoles")) {
99          fixHoles = true;
100       } else if (cmd.equals("-fix")) {
101         // make all fix options true
102         fixHoles = true;
103       } else {
104         String str = "Unknown command line option : " + cmd;
105         LOG.info(str);
106         System.out.println(str);
107         printUsageAndExit();
108       }
109     }
110 
111     // Fsck doesn't shutdown and and doesn't provide a way to shutdown its
112     // threads cleanly, so we do a System.exit.
113     boolean success = false;
114     try {
115       success = fsck.rebuildMeta(fixHoles);
116     } catch (MultipleIOException mioes) {
117       for (IOException ioe : mioes.getExceptions()) {
118         LOG.error("Bailed out due to:", ioe);
119       }
120     } catch (Exception e) {
121       LOG.error("Bailed out due to: ", e);
122     } finally {
123       System.exit(success ? 0 : 1);
124     }
125   }
126 }