001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master.cleaner; 019 020import org.apache.hadoop.conf.Configuration; 021import org.apache.hadoop.fs.FileStatus; 022import org.apache.hadoop.hbase.HBaseInterfaceAudience; 023import org.apache.hadoop.hbase.master.procedure.MasterProcedureUtil; 024import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 025import org.apache.yetus.audience.InterfaceAudience; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028 029/** 030 * Procedure WAL cleaner that uses the timestamp of the Procedure WAL to determine if it should be 031 * deleted. By default they are allowed to live for {@value #DEFAULT_TTL} 032 */ 033@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG) 034public class TimeToLiveProcedureWALCleaner extends BaseLogCleanerDelegate { 035 private static final Logger LOG = 036 LoggerFactory.getLogger(TimeToLiveProcedureWALCleaner.class.getName()); 037 public static final String TTL_CONF_KEY = "hbase.master.procedurewalcleaner.ttl"; 038 // default ttl = 7 days 039 public static final long DEFAULT_TTL = 604_800_000L; 040 // Configured time a procedure log can be kept after it was moved to the archive 041 private long ttl; 042 private boolean stopped = false; 043 044 @Override 045 public void setConf(Configuration conf) { 046 this.ttl = conf.getLong(TTL_CONF_KEY, DEFAULT_TTL); 047 super.setConf(conf); 048 } 049 050 @Override 051 public boolean isFileDeletable(FileStatus fStat) { 052 // Files are validated for the second time here, 053 // if it causes a bottleneck this logic needs refactored 054 if (!MasterProcedureUtil.validateProcedureWALFilename(fStat.getPath().getName())) { 055 return true; 056 } 057 058 long currentTime = EnvironmentEdgeManager.currentTime(); 059 long time = fStat.getModificationTime(); 060 long life = currentTime - time; 061 if (LOG.isTraceEnabled()) { 062 LOG.trace("Procedure log life:" + life + ", ttl:" + ttl + ", current:" + currentTime + 063 ", from: " + time); 064 } 065 if (life < 0) { 066 LOG.warn("Found a procedure log (" + fStat.getPath() + ") newer than current time (" 067 + currentTime + " < " + time + "), probably a clock skew"); 068 return false; 069 } 070 return life > ttl; 071 } 072 073 @Override 074 public void stop(String why) { 075 this.stopped = true; 076 } 077 078 @Override 079 public boolean isStopped() { 080 return this.stopped; 081 } 082}