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.mob;
20  
21  import java.io.IOException;
22  
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.conf.Configuration;
27  import org.apache.hadoop.conf.Configured;
28  import org.apache.hadoop.fs.FileSystem;
29  import org.apache.hadoop.hbase.HBaseConfiguration;
30  import org.apache.hadoop.hbase.HColumnDescriptor;
31  import org.apache.hadoop.hbase.HConstants;
32  import org.apache.hadoop.hbase.HTableDescriptor;
33  import org.apache.hadoop.hbase.TableName;
34  import org.apache.hadoop.hbase.client.HBaseAdmin;
35  import org.apache.hadoop.hbase.io.hfile.CacheConfig;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
38  import org.apache.hadoop.util.Tool;
39  import org.apache.hadoop.util.ToolRunner;
40  
41  import com.google.protobuf.ServiceException;
42  
43  /**
44   * The cleaner to delete the expired MOB files.
45   */
46  @InterfaceAudience.Private
47  public class ExpiredMobFileCleaner extends Configured implements Tool {
48  
49    private static final Log LOG = LogFactory.getLog(ExpiredMobFileCleaner.class);
50    /**
51     * Cleans the MOB files when they're expired and their min versions are 0.
52     * If the latest timestamp of Cells in a MOB file is older than the TTL in the column family,
53     * it's regarded as expired. This cleaner deletes them.
54     * At a time T0, the cells in a mob file M0 are expired. If a user starts a scan before T0, those
55     * mob cells are visible, this scan still runs after T0. At that time T1, this mob file M0
56     * is expired, meanwhile a cleaner starts, the M0 is archived and can be read in the archive
57     * directory.
58     * @param tableName The current table name.
59     * @param family The current family.
60     * @throws ServiceException
61     * @throws IOException
62     */
63    public void cleanExpiredMobFiles(String tableName, HColumnDescriptor family)
64        throws ServiceException, IOException {
65      Configuration conf = getConf();
66      TableName tn = TableName.valueOf(tableName);
67      FileSystem fs = FileSystem.get(conf);
68      LOG.info("Cleaning the expired MOB files of " + family.getNameAsString() + " in " + tableName);
69      // disable the block cache.
70      Configuration copyOfConf = new Configuration(conf);
71      copyOfConf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0f);
72      CacheConfig cacheConfig = new CacheConfig(copyOfConf);
73      MobUtils.cleanExpiredMobFiles(fs, conf, tn, family, cacheConfig,
74          EnvironmentEdgeManager.currentTime());
75    }
76  
77    public static void main(String[] args) throws Exception {
78      Configuration conf = HBaseConfiguration.create();
79      ToolRunner.run(conf, new ExpiredMobFileCleaner(), args);
80    }
81  
82    private void printUsage() {
83      System.err.println("Usage:\n" + "--------------------------\n"
84          + ExpiredMobFileCleaner.class.getName() + " tableName familyName");
85      System.err.println(" tableName        The table name");
86      System.err.println(" familyName       The column family name");
87    }
88  
89    public int run(String[] args) throws Exception {
90      if (args.length != 2) {
91        printUsage();
92        return 1;
93      }
94      String tableName = args[0];
95      String familyName = args[1];
96      TableName tn = TableName.valueOf(tableName);
97      HBaseAdmin.checkHBaseAvailable(getConf());
98      HBaseAdmin admin = new HBaseAdmin(getConf());
99      try {
100       HTableDescriptor htd = admin.getTableDescriptor(tn);
101       HColumnDescriptor family = htd.getFamily(Bytes.toBytes(familyName));
102       if (family == null || !family.isMobEnabled()) {
103         throw new IOException("Column family " + familyName + " is not a MOB column family");
104       }
105       if (family.getMinVersions() > 0) {
106         throw new IOException(
107             "The minVersions of the column family is not 0, could not be handled by this cleaner");
108       }
109       cleanExpiredMobFiles(tableName, family);
110       return 0;
111     } finally {
112       try {
113         admin.close();
114       } catch (IOException e) {
115         LOG.error("Failed to close the HBaseAdmin.", e);
116       }
117     }
118   }
119 
120 }