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.backup.master;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.List;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.fs.FileStatus;
29  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
30  import org.apache.hadoop.hbase.HConstants;
31  import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
32  import org.apache.hadoop.hbase.classification.InterfaceAudience;
33  import org.apache.hadoop.hbase.classification.InterfaceStability;
34  import org.apache.hadoop.hbase.client.Connection;
35  import org.apache.hadoop.hbase.client.ConnectionFactory;
36  import org.apache.hadoop.hbase.master.cleaner.BaseLogCleanerDelegate;
37  
38  /**
39   * Implementation of a log cleaner that checks if a log is still scheduled for
40   * incremental backup before deleting it when its TTL is over.
41   */
42  @InterfaceStability.Evolving
43  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
44  public class BackupLogCleaner extends BaseLogCleanerDelegate {
45    private static final Log LOG = LogFactory.getLog(BackupLogCleaner.class);
46  
47    private boolean stopped = false;
48  
49    public BackupLogCleaner() {
50    }
51  
52    @Override
53    public Iterable<FileStatus> getDeletableFiles(Iterable<FileStatus> files) {
54      // all members of this class are null if backup is disabled,
55      // so we cannot filter the files
56      if (this.getConf() == null) {
57        return files;
58      }
59      
60      List<FileStatus> list = new ArrayList<FileStatus>();
61      // TODO: LogCleaners do not have a way to get the Connection from Master. We should find a
62      // way to pass it down here, so that this connection is not re-created every time.
63      // It is expensive
64      try (final Connection conn = ConnectionFactory.createConnection(getConf());
65          final BackupSystemTable table = new BackupSystemTable(conn)) {
66        // If we do not have recorded backup sessions
67        if (!table.hasBackupSessions()) {
68          LOG.debug("BackupLogCleaner has no backup sessions");
69          return files;
70        }
71        
72        for(FileStatus file: files){
73          String wal = file.getPath().toString();
74          boolean logInSystemTable = table.isWALFileDeletable(wal);
75          if(LOG.isDebugEnabled()) {
76            if(logInSystemTable) {
77              LOG.debug("Found log file in hbase:backup, deleting: " + wal);
78              list.add(file);
79            } else {
80              LOG.debug("Didn't find this log in hbase:backup, keeping: " + wal);
81            }
82          }
83        }
84        return list;  
85      } catch (IOException e) {
86        LOG.error("Failed to get hbase:backup table, therefore will keep all files", e);
87        // nothing to delete
88        return new ArrayList<FileStatus>();
89      }
90    }
91  
92    @Override
93    public void setConf(Configuration config) {
94      // If backup is disabled, keep all members null
95      if (!config.getBoolean(HConstants.BACKUP_ENABLE_KEY, HConstants.BACKUP_ENABLE_DEFAULT)) {
96        LOG.warn("Backup is disabled - allowing all wals to be deleted");
97        return;
98      }
99      super.setConf(config);
100   }
101 
102   @Override
103   public void stop(String why) {
104     if (this.stopped) {
105       return;
106     }
107     this.stopped = true;
108     LOG.info("Stopping BackupLogCleaner");
109   }
110 
111   @Override
112   public boolean isStopped() {
113     return this.stopped;
114   }
115 
116 }