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.snapshot;
19  
20  import java.io.IOException;
21  import java.util.Arrays;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.classification.InterfaceAudience;
26  import org.apache.hadoop.classification.InterfaceStability;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.fs.FileStatus;
29  import org.apache.hadoop.fs.FileSystem;
30  import org.apache.hadoop.fs.Path;
31  import org.apache.hadoop.hbase.errorhandling.ForeignException;
32  import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher;
33  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
34  import org.apache.hadoop.hbase.util.FSUtils;
35  
36  /**
37   * Reference all the WAL files under a server's WAL directory
38   */
39  @InterfaceAudience.Private
40  @InterfaceStability.Evolving
41  public class ReferenceServerWALsTask extends SnapshotTask {
42    private static final Log LOG = LogFactory.getLog(ReferenceServerWALsTask.class);
43    private final FileSystem fs;
44    private final Configuration conf;
45    private final String serverName;
46    private Path logDir;
47  
48    /**
49     * @param snapshot snapshot being run
50     * @param failureListener listener to check for errors while running the operation and to
51     *          propagate errors found while running the task
52     * @param logDir log directory for the server. Name of the directory is taken as the name of the
53     *          server
54     * @param conf {@link Configuration} to extract filesystem information
55     * @param fs filesystem where the log files are stored and should be referenced
56     */
57    public ReferenceServerWALsTask(SnapshotDescription snapshot,
58        ForeignExceptionDispatcher failureListener, final Path logDir, final Configuration conf,
59        final FileSystem fs) {
60      super(snapshot, failureListener);
61      this.fs = fs;
62      this.conf = conf;
63      this.serverName = logDir.getName();
64      this.logDir = logDir;
65    }
66  
67    /**
68     * Create reference files (empty files with the same path and file name as original).
69     * @throws IOException exception from hdfs or network problems
70     * @throws ForeignException exception from an external procedure
71     */
72    @Override
73    public Void call() throws IOException, ForeignException {
74      // TODO switch to using a single file to reference all required WAL files
75  
76      // Iterate through each of the log files and add a reference to it.
77      // assumes that all the files under the server's logs directory is a log
78      FileStatus[] serverLogs = FSUtils.listStatus(fs, logDir, null);
79      if (serverLogs == null) {
80        LOG.debug("No logs for server directory:" + logDir + ", done referencing files.");
81        return null;
82      }
83  
84      if (LOG.isDebugEnabled()) {
85        LOG.debug("Adding references for WAL files:" + Arrays.toString(serverLogs));
86      }
87  
88      for (FileStatus file : serverLogs) {
89        this.rethrowException();
90  
91        // add the reference to the file. ex: hbase/.snapshots/.logs/<serverName>/<hlog>
92        Path rootDir = FSUtils.getRootDir(conf);
93        Path snapshotDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(this.snapshot, rootDir);
94        Path snapshotLogDir = TakeSnapshotUtils.getSnapshotHLogsDir(snapshotDir, serverName);
95        // actually store the reference on disk (small file)
96        Path ref = new Path(snapshotLogDir, file.getPath().getName());
97        if (!fs.createNewFile(ref)) {
98          if (!fs.exists(ref)) {
99            throw new IOException("Couldn't create reference for:" + file.getPath());
100         }
101       }
102       LOG.debug("Completed WAL referencing for: " + file.getPath() + " to " + ref);
103     }
104 
105     LOG.debug("Successfully completed WAL referencing for ALL files");
106     return null;
107   }
108 }