HBASE-17280 Add mechanism to control hbase cleaner behavior
Signed-off-by: tedyu <yuzhihong@gmail.com>
This commit is contained in:
parent
e9abe07629
commit
67fe516ec9
|
@ -766,6 +766,30 @@ public interface Admin extends Abortable, Closeable {
|
|||
*/
|
||||
boolean isCatalogJanitorEnabled() throws IOException;
|
||||
|
||||
/**
|
||||
* Enable/Disable the cleaner chore
|
||||
*
|
||||
* @param on if true enables the cleaner chore
|
||||
* @return the previous state
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean setCleanerChoreRunning(final boolean on) throws IOException;
|
||||
|
||||
/**
|
||||
* Ask for cleaner chore to run
|
||||
*
|
||||
* @return True if cleaner chore ran, false otherwise
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean runCleanerChore() throws IOException;
|
||||
|
||||
/**
|
||||
* Query on the cleaner chore state (Enabled/Disabled?)
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean isCleanerChoreEnabled() throws IOException;
|
||||
|
||||
/**
|
||||
* Merge two regions. Asynchronous operation.
|
||||
*
|
||||
|
|
|
@ -128,6 +128,8 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabled
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCleanerChoreEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCleanerChoreEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsNormalizerEnabledRequest;
|
||||
|
@ -164,10 +166,14 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRe
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetCleanerChoreRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetCleanerChoreRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetQuotaRequest;
|
||||
|
@ -1930,6 +1936,25 @@ class ConnectionManager {
|
|||
return stub.isCatalogJanitorEnabled(controller, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunCleanerChoreResponse runCleanerChore(RpcController controller,
|
||||
RunCleanerChoreRequest request) throws ServiceException {
|
||||
return stub.runCleanerChore(controller, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetCleanerChoreRunningResponse setCleanerChoreRunning(RpcController controller,
|
||||
SetCleanerChoreRunningRequest request) throws ServiceException {
|
||||
return stub.setCleanerChoreRunning(controller, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsCleanerChoreEnabledResponse isCleanerChoreEnabled(
|
||||
RpcController controller, IsCleanerChoreEnabledRequest request)
|
||||
throws ServiceException {
|
||||
return stub.isCleanerChoreEnabled(controller, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoprocessorServiceResponse execMasterService(
|
||||
RpcController controller, CoprocessorServiceRequest request)
|
||||
|
|
|
@ -2552,6 +2552,39 @@ public class HBaseAdmin implements Admin {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setCleanerChoreRunning(final boolean on) throws IOException {
|
||||
return executeCallable(new MasterCallable<Boolean>(getConnection()) {
|
||||
@Override
|
||||
public Boolean call(int callTimeout) throws ServiceException {
|
||||
return master.setCleanerChoreRunning(null,
|
||||
RequestConverter.buildSetCleanerChoreRunningRequest(on)).getPrevValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runCleanerChore() throws IOException {
|
||||
return executeCallable(new MasterCallable<Boolean>(getConnection()) {
|
||||
@Override
|
||||
public Boolean call(int callTimeout) throws ServiceException {
|
||||
return master.runCleanerChore(null, RequestConverter.buildCleanerChoreRequest())
|
||||
.getCleanerChoreRan();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCleanerChoreEnabled() throws IOException {
|
||||
return executeCallable(new MasterCallable<Boolean>(getConnection()) {
|
||||
@Override
|
||||
public Boolean call(int callTimeout) throws ServiceException {
|
||||
return master.isCleanerChoreEnabled(null,
|
||||
RequestConverter.buildIsCleanerChoreEnabledRequest()).getValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isEncodedRegionName(byte[] regionName) throws IOException {
|
||||
try {
|
||||
HRegionInfo.parseRegionName(regionName);
|
||||
|
|
|
@ -89,12 +89,14 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DisableTableReque
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetCleanerChoreRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCleanerChoreEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsNormalizerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsSplitOrMergeEnabledRequest;
|
||||
|
@ -104,6 +106,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MoveRegionRequest
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.NormalizeRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.OfflineRegionRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledRequest;
|
||||
|
@ -1485,6 +1488,42 @@ public final class RequestConverter {
|
|||
return IS_CATALOG_JANITOR_ENABLED_REQUEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link #buildCleanerChoreRequest}
|
||||
*/
|
||||
private static final RunCleanerChoreRequest CLEANER_CHORE_REQUEST = RunCleanerChoreRequest
|
||||
.newBuilder().build();
|
||||
|
||||
/**
|
||||
* Creates a request for running cleaner chore
|
||||
* @return A {@link RunCleanerChoreRequest}
|
||||
*/
|
||||
public static RunCleanerChoreRequest buildCleanerChoreRequest() {
|
||||
return CLEANER_CHORE_REQUEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a request for enabling/disabling the cleaner chore
|
||||
* @return A {@link SetCleanerChoreRunningRequest}
|
||||
*/
|
||||
public static SetCleanerChoreRunningRequest buildSetCleanerChoreRunningRequest(boolean on) {
|
||||
return SetCleanerChoreRunningRequest.newBuilder().setOn(on).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link #buildIsCleanerChoreEnabledRequest()}
|
||||
*/
|
||||
private static final IsCleanerChoreEnabledRequest IS_CLEANER_CHORE_ENABLED_REQUEST =
|
||||
IsCleanerChoreEnabledRequest.newBuilder().build();
|
||||
|
||||
/**
|
||||
* Creates a request for querying the master whether the cleaner chore is enabled
|
||||
* @return A {@link IsCleanerChoreEnabledRequest}
|
||||
*/
|
||||
public static IsCleanerChoreEnabledRequest buildIsCleanerChoreEnabledRequest() {
|
||||
return IS_CLEANER_CHORE_ENABLED_REQUEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a request for querying the master the last flushed sequence Id for a region
|
||||
* @param regionName
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameInt64Pair;
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MapReduceProtos.ScanMetrics;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableCatalogJanitorResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdResponse;
|
||||
import org.apache.hadoop.hbase.regionserver.RegionOpeningState;
|
||||
import org.apache.hadoop.hbase.security.access.UserPermission;
|
||||
|
@ -303,6 +304,14 @@ public final class ResponseConverter {
|
|||
return EnableCatalogJanitorResponse.newBuilder().setPrevValue(prevValue).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a response for the cleaner chore request
|
||||
* @return A RunCleanerChoreResponse
|
||||
*/
|
||||
public static RunCleanerChoreResponse buildRunCleanerChoreResponse(boolean ran) {
|
||||
return RunCleanerChoreResponse.newBuilder().setCleanerChoreRan(ran).build();
|
||||
}
|
||||
|
||||
// End utilities for Admin
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -345,6 +345,28 @@ message IsCatalogJanitorEnabledResponse {
|
|||
required bool value = 1;
|
||||
}
|
||||
|
||||
message RunCleanerChoreRequest {
|
||||
}
|
||||
|
||||
message RunCleanerChoreResponse {
|
||||
required bool cleaner_chore_ran = 1;
|
||||
}
|
||||
|
||||
message SetCleanerChoreRunningRequest {
|
||||
required bool on = 1;
|
||||
}
|
||||
|
||||
message SetCleanerChoreRunningResponse {
|
||||
optional bool prev_value = 1;
|
||||
}
|
||||
|
||||
message IsCleanerChoreEnabledRequest {
|
||||
}
|
||||
|
||||
message IsCleanerChoreEnabledResponse {
|
||||
required bool value = 1;
|
||||
}
|
||||
|
||||
message SnapshotRequest {
|
||||
required SnapshotDescription snapshot = 1;
|
||||
}
|
||||
|
@ -699,6 +721,22 @@ service MasterService {
|
|||
rpc IsCatalogJanitorEnabled(IsCatalogJanitorEnabledRequest)
|
||||
returns(IsCatalogJanitorEnabledResponse);
|
||||
|
||||
/** Get a run of the cleaner chore*/
|
||||
rpc RunCleanerChore(RunCleanerChoreRequest)
|
||||
returns(RunCleanerChoreResponse);
|
||||
|
||||
/**
|
||||
* Enable the cleaner chore on or off.
|
||||
*/
|
||||
rpc SetCleanerChoreRunning(SetCleanerChoreRunningRequest)
|
||||
returns(SetCleanerChoreRunningResponse);
|
||||
|
||||
/**
|
||||
* Query whether the cleaner chore is enabled.
|
||||
*/
|
||||
rpc IsCleanerChoreEnabled(IsCleanerChoreEnabledRequest)
|
||||
returns(IsCleanerChoreEnabledResponse);
|
||||
|
||||
/**
|
||||
* Call a master coprocessor endpoint
|
||||
*/
|
||||
|
|
|
@ -1053,6 +1053,20 @@ public class HMaster extends HRegionServer implements MasterServices, Server {
|
|||
catalogJanitorChore.getEnabled() : false;
|
||||
}
|
||||
|
||||
boolean isCleanerChoreEnabled() {
|
||||
boolean hfileCleanerFlag = true, logCleanerFlag = true;
|
||||
|
||||
if (hfileCleaner != null) {
|
||||
hfileCleanerFlag = hfileCleaner.getEnabled();
|
||||
}
|
||||
|
||||
if(logCleaner != null) {
|
||||
logCleanerFlag = logCleaner.getEnabled();
|
||||
}
|
||||
|
||||
return (hfileCleanerFlag && logCleanerFlag);
|
||||
}
|
||||
|
||||
private void splitMetaLogBeforeAssignment(ServerName currentMetaServer) throws IOException {
|
||||
if (RecoveryMode.LOG_REPLAY == this.getMasterFileSystem().getLogRecoveryMode()) {
|
||||
// In log replay mode, we mark hbase:meta region as recovering in ZK
|
||||
|
@ -2713,6 +2727,10 @@ public class HMaster extends HRegionServer implements MasterServices, Server {
|
|||
return this.hfileCleaner;
|
||||
}
|
||||
|
||||
public LogCleaner getLogCleaner() {
|
||||
return this.logCleaner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the underlying snapshot manager
|
||||
*/
|
||||
|
|
|
@ -107,6 +107,8 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequ
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCleanerChoreEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCleanerChoreEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsInMaintenanceModeRequest;
|
||||
|
@ -149,11 +151,15 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotRe
|
|||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCatalogScanResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.RunCleanerChoreResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse.Capability;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetBalancerRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetCleanerChoreRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetCleanerChoreRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningRequest;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetNormalizerRunningResponse;
|
||||
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetQuotaRequest;
|
||||
|
@ -649,6 +655,21 @@ public class MasterRpcServices extends RSRpcServices
|
|||
master.catalogJanitorChore.setEnabled(req.getEnable())).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetCleanerChoreRunningResponse setCleanerChoreRunning(RpcController c,
|
||||
SetCleanerChoreRunningRequest req) throws ServiceException {
|
||||
try {
|
||||
master.checkInitialized();
|
||||
} catch (IOException ioe) {
|
||||
throw new ServiceException(ioe);
|
||||
}
|
||||
boolean prevValue =
|
||||
master.getLogCleaner().getEnabled() && master.getHFileCleaner().getEnabled();
|
||||
master.getLogCleaner().setEnabled(req.getOn());
|
||||
master.getHFileCleaner().setEnabled(req.getOn());
|
||||
return SetCleanerChoreRunningResponse.newBuilder().setPrevValue(prevValue).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnableTableResponse enableTable(RpcController controller,
|
||||
EnableTableRequest request) throws ServiceException {
|
||||
|
@ -941,6 +962,13 @@ public class MasterRpcServices extends RSRpcServices
|
|||
master.isCatalogJanitorEnabled()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsCleanerChoreEnabledResponse isCleanerChoreEnabled(RpcController c,
|
||||
IsCleanerChoreEnabledRequest req) throws ServiceException {
|
||||
return IsCleanerChoreEnabledResponse.newBuilder()
|
||||
.setValue(master.isCleanerChoreEnabled()).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsMasterRunningResponse isMasterRunning(RpcController c,
|
||||
IsMasterRunningRequest req) throws ServiceException {
|
||||
|
@ -1303,6 +1331,19 @@ public class MasterRpcServices extends RSRpcServices
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RunCleanerChoreResponse runCleanerChore(RpcController c, RunCleanerChoreRequest req)
|
||||
throws ServiceException {
|
||||
try {
|
||||
master.checkInitialized();
|
||||
Boolean result = master.getHFileCleaner().runCleaner()
|
||||
&& master.getLogCleaner().runCleaner();
|
||||
return ResponseConverter.buildRunCleanerChoreResponse(result);
|
||||
} catch (IOException ioe) {
|
||||
throw new ServiceException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetBalancerRunningResponse setBalancerRunning(RpcController c,
|
||||
SetBalancerRunningRequest req) throws ServiceException {
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.master.cleaner;
|
|||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -49,6 +50,7 @@ public abstract class CleanerChore<T extends FileCleanerDelegate> extends Schedu
|
|||
private final Path oldFileDir;
|
||||
private final Configuration conf;
|
||||
protected List<T> cleanersChain;
|
||||
private AtomicBoolean enabled = new AtomicBoolean(true);
|
||||
|
||||
/**
|
||||
* @param name name of the chore being run
|
||||
|
@ -119,13 +121,23 @@ public abstract class CleanerChore<T extends FileCleanerDelegate> extends Schedu
|
|||
|
||||
@Override
|
||||
protected void chore() {
|
||||
if (getEnabled()) {
|
||||
runCleaner();
|
||||
} else {
|
||||
LOG.debug("Cleaner disabled! Not cleaning.");
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean runCleaner() {
|
||||
try {
|
||||
FileStatus[] files = FSUtils.listStatus(this.fs, this.oldFileDir);
|
||||
checkAndDeleteEntries(files);
|
||||
} catch (IOException e) {
|
||||
e = RemoteExceptionHandler.checkIOException(e);
|
||||
LOG.warn("Error while cleaning the logs", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,4 +291,15 @@ public abstract class CleanerChore<T extends FileCleanerDelegate> extends Schedu
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enabled
|
||||
*/
|
||||
public boolean setEnabled(final boolean enabled) {
|
||||
return this.enabled.getAndSet(enabled);
|
||||
}
|
||||
|
||||
public boolean getEnabled() {
|
||||
return this.enabled.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -288,6 +288,72 @@ public class TestCleanerChore {
|
|||
Mockito.verify(spy, Mockito.times(1)).isFileDeletable(Mockito.any(FileStatus.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFileWithCleanerEnabled() throws Exception {
|
||||
Stoppable stop = new StoppableImplementation();
|
||||
Configuration conf = UTIL.getConfiguration();
|
||||
Path testDir = UTIL.getDataTestDir();
|
||||
FileSystem fs = UTIL.getTestFileSystem();
|
||||
String confKey = "hbase.test.cleaner.delegates";
|
||||
conf.set(confKey, AlwaysDelete.class.getName());
|
||||
|
||||
AllValidPaths chore = new AllValidPaths("test-file-cleaner", stop, conf, fs, testDir, confKey);
|
||||
|
||||
// Enable cleaner
|
||||
chore.setEnabled(true);
|
||||
|
||||
// create the directory layout in the directory to clean
|
||||
Path parent = new Path(testDir, "parent");
|
||||
Path child = new Path(parent, "child");
|
||||
Path file = new Path(child, "someFile");
|
||||
fs.mkdirs(child);
|
||||
|
||||
// touch a new file
|
||||
fs.create(file).close();
|
||||
assertTrue("Test file didn't get created.", fs.exists(file));
|
||||
|
||||
// run the chore
|
||||
chore.chore();
|
||||
|
||||
// verify all the files got deleted
|
||||
assertFalse("File didn't get deleted", fs.exists(file));
|
||||
assertFalse("Empty directory didn't get deleted", fs.exists(child));
|
||||
assertFalse("Empty directory didn't get deleted", fs.exists(parent));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFileWithCleanerDisabled() throws Exception {
|
||||
Stoppable stop = new StoppableImplementation();
|
||||
Configuration conf = UTIL.getConfiguration();
|
||||
Path testDir = UTIL.getDataTestDir();
|
||||
FileSystem fs = UTIL.getTestFileSystem();
|
||||
String confKey = "hbase.test.cleaner.delegates";
|
||||
conf.set(confKey, AlwaysDelete.class.getName());
|
||||
|
||||
AllValidPaths chore = new AllValidPaths("test-file-cleaner", stop, conf, fs, testDir, confKey);
|
||||
|
||||
// Disable cleaner
|
||||
chore.setEnabled(false);
|
||||
|
||||
// create the directory layout in the directory to clean
|
||||
Path parent = new Path(testDir, "parent");
|
||||
Path child = new Path(parent, "child");
|
||||
Path file = new Path(child, "someFile");
|
||||
fs.mkdirs(child);
|
||||
|
||||
// touch a new file
|
||||
fs.create(file).close();
|
||||
assertTrue("Test file didn't get created.", fs.exists(file));
|
||||
|
||||
// run the chore
|
||||
chore.chore();
|
||||
|
||||
// verify all the files got deleted
|
||||
assertTrue("File got deleted with cleaner disabled", fs.exists(file));
|
||||
assertTrue("Directory got deleted", fs.exists(child));
|
||||
assertTrue("Directory got deleted", fs.exists(parent));
|
||||
}
|
||||
|
||||
private static class AllValidPaths extends CleanerChore<BaseHFileCleanerDelegate> {
|
||||
|
||||
public AllValidPaths(String name, Stoppable s, Configuration conf, FileSystem fs,
|
||||
|
|
|
@ -210,6 +210,26 @@ module Hbase
|
|||
@admin.isCatalogJanitorEnabled()
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Request cleaner chore (for garbage collection of HFiles and WAL files)
|
||||
def cleaner_chore_run()
|
||||
@admin.runCleanerChore()
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Enable/disable the cleaner chore
|
||||
# Returns previous cleaner chore switch setting.
|
||||
def cleaner_chore_switch(enableDisable)
|
||||
@admin.setCleanerChoreRunning(java.lang.Boolean::valueOf(enableDisable))
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Query on the cleaner chore state (enabled/disabled?)
|
||||
# Returns cleaner chore state (true signifies enabled).
|
||||
def cleaner_chore_enabled()
|
||||
@admin.isCleanerChoreEnabled()
|
||||
end
|
||||
|
||||
#----------------------------------------------------------------------------------------------
|
||||
# Enables a table
|
||||
def enable(table_name)
|
||||
|
|
|
@ -335,6 +335,9 @@ Shell.load_command_group(
|
|||
catalogjanitor_run
|
||||
catalogjanitor_switch
|
||||
catalogjanitor_enabled
|
||||
cleaner_chore_run
|
||||
cleaner_chore_switch
|
||||
cleaner_chore_enabled
|
||||
compact_rs
|
||||
compaction_state
|
||||
trace
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
module Shell
|
||||
module Commands
|
||||
class CleanerChoreEnabled < Command
|
||||
def help
|
||||
return <<-EOF
|
||||
Query for the Cleaner chore state (enabled/disabled?).
|
||||
Examples:
|
||||
|
||||
hbase> cleaner_chore_enabled
|
||||
EOF
|
||||
end
|
||||
|
||||
def command()
|
||||
format_simple_command do
|
||||
formatter.row([
|
||||
admin.cleaner_chore_enabled()? "true" : "false"
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
module Shell
|
||||
module Commands
|
||||
class CleanerChoreRun < Command
|
||||
def help
|
||||
return <<-EOF
|
||||
Cleaner command for garbage collection of HFiles and WAL files.
|
||||
|
||||
hbase> cleaner_chore_run
|
||||
|
||||
EOF
|
||||
end
|
||||
def command()
|
||||
format_simple_command do
|
||||
admin.cleaner_chore_run()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
module Shell
|
||||
module Commands
|
||||
class CleanerChoreSwitch < Command
|
||||
def help
|
||||
return <<-EOF
|
||||
Enable/Disable Cleaner chore. Returns previous Cleaner chore state.
|
||||
Examples:
|
||||
|
||||
hbase> cleaner_chore_switch true
|
||||
hbase> cleaner_chore_switch false
|
||||
EOF
|
||||
end
|
||||
|
||||
def command(enableDisable)
|
||||
format_simple_command do
|
||||
formatter.row([
|
||||
admin.cleaner_chore_switch(enableDisable)? "true" : "false"
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue