View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.util;
20  
21  import java.io.IOException;
22  import java.util.NavigableSet;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.fs.FileStatus;
28  import org.apache.hadoop.fs.FileSystem;
29  import org.apache.hadoop.fs.Path;
30  import org.apache.hadoop.fs.PathFilter;
31  import org.apache.hadoop.hbase.HConstants;
32  import org.apache.hadoop.hbase.wal.WALSplitter;
33  
34  /**
35   * Utility methods for interacting with the hbase.root file system.
36   */
37  @InterfaceAudience.Private
38  public final class FSVisitor {
39    private static final Log LOG = LogFactory.getLog(FSVisitor.class);
40  
41    public interface RegionVisitor {
42      void region(final String region) throws IOException;
43    }
44  
45    public interface StoreFileVisitor {
46      void storeFile(final String region, final String family, final String hfileName)
47         throws IOException;
48    }
49  
50    public interface RecoveredEditsVisitor {
51      void recoveredEdits (final String region, final String logfile)
52        throws IOException;
53    }
54  
55    public interface LogFileVisitor {
56      void logFile (final String server, final String logfile)
57        throws IOException;
58    }
59  
60    private FSVisitor() {
61      // private constructor for utility class
62    }
63  
64    /**
65     * Iterate over the table store files
66     *
67     * @param fs {@link FileSystem}
68     * @param tableDir {@link Path} to the table directory
69     * @param visitor callback object to get the store files
70     * @throws IOException if an error occurred while scanning the directory
71     */
72    public static void visitRegions(final FileSystem fs, final Path tableDir,
73        final RegionVisitor visitor) throws IOException {
74      FileStatus[] regions = FSUtils.listStatus(fs, tableDir, new FSUtils.RegionDirFilter(fs));
75      if (regions == null) {
76        if (LOG.isTraceEnabled()) {
77          LOG.trace("No regions under directory:" + tableDir);
78        }
79        return;
80      }
81  
82      for (FileStatus region: regions) {
83        visitor.region(region.getPath().getName());
84      }
85    }
86  
87    /**
88     * Iterate over the table store files
89     *
90     * @param fs {@link FileSystem}
91     * @param tableDir {@link Path} to the table directory
92     * @param visitor callback object to get the store files
93     * @throws IOException if an error occurred while scanning the directory
94     */
95    public static void visitTableStoreFiles(final FileSystem fs, final Path tableDir,
96        final StoreFileVisitor visitor) throws IOException {
97      FileStatus[] regions = FSUtils.listStatus(fs, tableDir, new FSUtils.RegionDirFilter(fs));
98      if (regions == null) {
99        if (LOG.isTraceEnabled()) {
100         LOG.trace("No regions under directory:" + tableDir);
101       }
102       return;
103     }
104 
105     for (FileStatus region: regions) {
106       visitRegionStoreFiles(fs, region.getPath(), visitor);
107     }
108   }
109 
110   /**
111    * Iterate over the region store files
112    *
113    * @param fs {@link FileSystem}
114    * @param regionDir {@link Path} to the region directory
115    * @param visitor callback object to get the store files
116    * @throws IOException if an error occurred while scanning the directory
117    */
118   public static void visitRegionStoreFiles(final FileSystem fs, final Path regionDir,
119       final StoreFileVisitor visitor) throws IOException {
120     FileStatus[] families = FSUtils.listStatus(fs, regionDir, new FSUtils.FamilyDirFilter(fs));
121     if (families == null) {
122       if (LOG.isTraceEnabled()) {
123         LOG.trace("No families under region directory:" + regionDir);
124       }
125       return;
126     }
127 
128     PathFilter fileFilter = new FSUtils.FileFilter(fs);
129     for (FileStatus family: families) {
130       Path familyDir = family.getPath();
131       String familyName = familyDir.getName();
132 
133       // get all the storeFiles in the family
134       FileStatus[] storeFiles = FSUtils.listStatus(fs, familyDir, fileFilter);
135       if (storeFiles == null) {
136         if (LOG.isTraceEnabled()) {
137           LOG.trace("No hfiles found for family: " + familyDir + ", skipping.");
138         }
139         continue;
140       }
141 
142       for (FileStatus hfile: storeFiles) {
143         Path hfilePath = hfile.getPath();
144         visitor.storeFile(regionDir.getName(), familyName, hfilePath.getName());
145       }
146     }
147   }
148 
149   /**
150    * Iterate over each region in the table and inform about recovered.edits
151    *
152    * @param fs {@link FileSystem}
153    * @param tableDir {@link Path} to the table directory
154    * @param visitor callback object to get the recovered.edits files
155    * @throws IOException if an error occurred while scanning the directory
156    */
157   public static void visitTableRecoveredEdits(final FileSystem fs, final Path tableDir,
158       final FSVisitor.RecoveredEditsVisitor visitor) throws IOException {
159     FileStatus[] regions = FSUtils.listStatus(fs, tableDir, new FSUtils.RegionDirFilter(fs));
160     if (regions == null) {
161       if (LOG.isTraceEnabled()) {
162         LOG.trace("No recoveredEdits regions under directory:" + tableDir);
163       }
164       return;
165     }
166 
167     for (FileStatus region: regions) {
168       visitRegionRecoveredEdits(fs, region.getPath(), visitor);
169     }
170   }
171 
172   /**
173    * Iterate over recovered.edits of the specified region
174    *
175    * @param fs {@link FileSystem}
176    * @param regionDir {@link Path} to the Region directory
177    * @param visitor callback object to get the recovered.edits files
178    * @throws IOException if an error occurred while scanning the directory
179    */
180   public static void visitRegionRecoveredEdits(final FileSystem fs, final Path regionDir,
181       final FSVisitor.RecoveredEditsVisitor visitor) throws IOException {
182     NavigableSet<Path> files = WALSplitter.getSplitEditFilesSorted(fs, regionDir);
183     if (files == null || files.size() == 0) return;
184 
185     for (Path source: files) {
186       // check to see if the file is zero length, in which case we can skip it
187       FileStatus stat = fs.getFileStatus(source);
188       if (stat.getLen() <= 0) continue;
189 
190       visitor.recoveredEdits(regionDir.getName(), source.getName());
191     }
192   }
193 
194   /**
195    * Iterate over hbase log files
196    *
197    * @param fs {@link FileSystem}
198    * @param rootDir {@link Path} to the HBase root folder
199    * @param visitor callback object to get the log files
200    * @throws IOException if an error occurred while scanning the directory
201    */
202   public static void visitLogFiles(final FileSystem fs, final Path rootDir,
203       final LogFileVisitor visitor) throws IOException {
204     Path logsDir = new Path(rootDir, HConstants.HREGION_LOGDIR_NAME);
205     FileStatus[] logServerDirs = FSUtils.listStatus(fs, logsDir);
206     if (logServerDirs == null) {
207       if (LOG.isTraceEnabled()) {
208         LOG.trace("No logs under directory:" + logsDir);
209       }
210       return;
211     }
212 
213     for (FileStatus serverLogs: logServerDirs) {
214       String serverName = serverLogs.getPath().getName();
215 
216       FileStatus[] wals = FSUtils.listStatus(fs, serverLogs.getPath());
217       if (wals == null) {
218         if (LOG.isTraceEnabled()) {
219           LOG.trace("No wals found for server: " + serverName + ", skipping.");
220         }
221         continue;
222       }
223 
224       for (FileStatus walRef: wals) {
225         visitor.logFile(serverName, walRef.getPath().getName());
226       }
227     }
228   }
229 }