001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.mob; 020 021import java.io.IOException; 022 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.conf.Configured; 025import org.apache.hadoop.fs.FileSystem; 026import org.apache.hadoop.hbase.HBaseConfiguration; 027import org.apache.hadoop.hbase.HConstants; 028import org.apache.hadoop.hbase.TableName; 029import org.apache.yetus.audience.InterfaceAudience; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032import org.apache.hadoop.hbase.client.Admin; 033import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 034import org.apache.hadoop.hbase.client.Connection; 035import org.apache.hadoop.hbase.client.ConnectionFactory; 036import org.apache.hadoop.hbase.client.HBaseAdmin; 037import org.apache.hadoop.hbase.client.TableDescriptor; 038import org.apache.hadoop.hbase.io.hfile.CacheConfig; 039import org.apache.hadoop.hbase.util.Bytes; 040import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 041import org.apache.hadoop.util.Tool; 042import org.apache.hadoop.util.ToolRunner; 043 044/** 045 * The cleaner to delete the expired MOB files. 046 */ 047@InterfaceAudience.Private 048public class ExpiredMobFileCleaner extends Configured implements Tool { 049 050 private static final Logger LOG = LoggerFactory.getLogger(ExpiredMobFileCleaner.class); 051 /** 052 * Cleans the MOB files when they're expired and their min versions are 0. 053 * If the latest timestamp of Cells in a MOB file is older than the TTL in the column family, 054 * it's regarded as expired. This cleaner deletes them. 055 * At a time T0, the cells in a mob file M0 are expired. If a user starts a scan before T0, those 056 * mob cells are visible, this scan still runs after T0. At that time T1, this mob file M0 057 * is expired, meanwhile a cleaner starts, the M0 is archived and can be read in the archive 058 * directory. 059 * @param tableName The current table name. 060 * @param family The current family. 061 */ 062 public void cleanExpiredMobFiles(String tableName, ColumnFamilyDescriptor family) throws IOException { 063 Configuration conf = getConf(); 064 TableName tn = TableName.valueOf(tableName); 065 FileSystem fs = FileSystem.get(conf); 066 LOG.info("Cleaning the expired MOB files of " + family.getNameAsString() + " in " + tableName); 067 // disable the block cache. 068 Configuration copyOfConf = new Configuration(conf); 069 copyOfConf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0f); 070 CacheConfig cacheConfig = new CacheConfig(copyOfConf); 071 MobUtils.cleanExpiredMobFiles(fs, conf, tn, family, cacheConfig, 072 EnvironmentEdgeManager.currentTime()); 073 } 074 075 public static void main(String[] args) throws Exception { 076 Configuration conf = HBaseConfiguration.create(); 077 ToolRunner.run(conf, new ExpiredMobFileCleaner(), args); 078 } 079 080 private void printUsage() { 081 System.err.println("Usage:\n" + "--------------------------\n" 082 + ExpiredMobFileCleaner.class.getName() + " tableName familyName"); 083 System.err.println(" tableName The table name"); 084 System.err.println(" familyName The column family name"); 085 } 086 087 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="REC_CATCH_EXCEPTION", 088 justification="Intentional") 089 @Override 090 public int run(String[] args) throws Exception { 091 if (args.length != 2) { 092 printUsage(); 093 return 1; 094 } 095 String tableName = args[0]; 096 String familyName = args[1]; 097 TableName tn = TableName.valueOf(tableName); 098 HBaseAdmin.available(getConf()); 099 Connection connection = ConnectionFactory.createConnection(getConf()); 100 Admin admin = connection.getAdmin(); 101 try { 102 TableDescriptor htd = admin.getDescriptor(tn); 103 ColumnFamilyDescriptor family = htd.getColumnFamily(Bytes.toBytes(familyName)); 104 if (family == null || !family.isMobEnabled()) { 105 throw new IOException("Column family " + familyName + " is not a MOB column family"); 106 } 107 if (family.getMinVersions() > 0) { 108 throw new IOException( 109 "The minVersions of the column family is not 0, could not be handled by this cleaner"); 110 } 111 cleanExpiredMobFiles(tableName, family); 112 return 0; 113 } finally { 114 try { 115 admin.close(); 116 } catch (IOException e) { 117 LOG.error("Failed to close the HBaseAdmin.", e); 118 } 119 try { 120 connection.close(); 121 } catch (IOException e) { 122 LOG.error("Failed to close the connection.", e); 123 } 124 } 125 } 126}