/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.zookeeper.server; import java.io.File; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class manages the cleanup of snapshots and corresponding transaction * logs by scheduling the auto purge task with the specified * 'autopurge.purgeInterval'. It keeps the most recent * 'autopurge.snapRetainCount' number of snapshots and corresponding transaction * logs. */ public class DatadirCleanupManager { private static final Logger LOG = LoggerFactory.getLogger(DatadirCleanupManager.class); /** * Status of the dataDir purge task */ public enum PurgeTaskStatus { NOT_STARTED, STARTED, COMPLETED; } private PurgeTaskStatus purgeTaskStatus = PurgeTaskStatus.NOT_STARTED; private final String snapDir; private final String dataLogDir; private final int snapRetainCount; private final int purgeInterval; private Timer timer; /** * Constructor of DatadirCleanupManager. It takes the parameters to schedule * the purge task. * * @param snapDir * snapshot directory * @param dataLogDir * transaction log directory * @param snapRetainCount * number of snapshots to be retained after purge * @param purgeInterval * purge interval in hours */ public DatadirCleanupManager(String snapDir, String dataLogDir, int snapRetainCount, int purgeInterval) { this.snapDir = snapDir; this.dataLogDir = dataLogDir; this.snapRetainCount = snapRetainCount; this.purgeInterval = purgeInterval; LOG.info("autopurge.snapRetainCount set to " + snapRetainCount); LOG.info("autopurge.purgeInterval set to " + purgeInterval); } /** * Validates the purge configuration and schedules the purge task. Purge * task keeps the most recent <code>snapRetainCount</code> number of * snapshots and deletes the remaining for every <code>purgeInterval</code> * hour(s). * <p> * <code>purgeInterval</code> of <code>0</code> or * <code>negative integer</code> will not schedule the purge task. * </p> * * @see PurgeTxnLog#purge(File, File, int) */ public void start() { if (PurgeTaskStatus.STARTED == purgeTaskStatus) { LOG.warn("Purge task is already running."); return; } // Don't schedule the purge task with zero or negative purge interval. if (purgeInterval <= 0) { LOG.info("Purge task is not scheduled."); return; } timer = new Timer("PurgeTask", true); TimerTask task = new PurgeTask(dataLogDir, snapDir, snapRetainCount); timer.scheduleAtFixedRate(task, 0, TimeUnit.HOURS.toMillis(purgeInterval)); purgeTaskStatus = PurgeTaskStatus.STARTED; } /** * Shutdown the purge task. */ public void shutdown() { if (PurgeTaskStatus.STARTED == purgeTaskStatus) { LOG.info("Shutting down purge task."); timer.cancel(); purgeTaskStatus = PurgeTaskStatus.COMPLETED; } else { LOG.warn("Purge task not started. Ignoring shutdown!"); } } static class PurgeTask extends TimerTask { private String logsDir; private String snapsDir; private int snapRetainCount; public PurgeTask(String dataDir, String snapDir, int count) { logsDir = dataDir; snapsDir = snapDir; snapRetainCount = count; } @Override public void run() { LOG.info("Purge task started."); try { PurgeTxnLog.purge(new File(logsDir), new File(snapsDir), snapRetainCount); } catch (Exception e) { LOG.error("Error occured while purging.", e); } LOG.info("Purge task completed."); } } /** * Returns the status of the purge task. * * @return the status of the purge task */ public PurgeTaskStatus getPurgeTaskStatus() { return purgeTaskStatus; } /** * Returns the snapshot directory. * * @return the snapshot directory. */ public String getSnapDir() { return snapDir; } /** * Returns transaction log directory. * * @return the transaction log directory. */ public String getDataLogDir() { return dataLogDir; } /** * Returns purge interval in hours. * * @return the purge interval in hours. */ public int getPurgeInterval() { return purgeInterval; } /** * Returns the number of snapshots to be retained after purge. * * @return the number of snapshots to be retained after purge. */ public int getSnapRetainCount() { return snapRetainCount; } }