diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptor.java index 817f9e2d4b1b..f5702edcd518 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptor.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptor.java @@ -212,6 +212,13 @@ public interface TableDescriptor { */ boolean isCompactionEnabled(); + /** + * Check if the compaction only remove expired file, skipping merge files flag of the table is + * true. If flag is false then do normal compactions. + * @return true if table compaction only remove expired file, skipping merge files. + */ + boolean shouldSkipMergingCompaction(); + /** * Check if the split enable flag of the table is true. If flag is false then no region split will * be done. diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorBuilder.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorBuilder.java index 8636b006e83d..e3da6a069124 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorBuilder.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/TableDescriptorBuilder.java @@ -85,6 +85,15 @@ public class TableDescriptorBuilder { public static final String COMPACTION_ENABLED = "COMPACTION_ENABLED"; private static final Bytes COMPACTION_ENABLED_KEY = new Bytes(Bytes.toBytes(COMPACTION_ENABLED)); + /** + * Used by HBase Shell interface to access this metadata attribute which denotes if the table + * compact only remove expired file, skipping merge files. + */ + @InterfaceAudience.Private + public static final String SKIP_MERGING_COMPACTION = "SKIP_MERGING_COMPACTION"; + private static final Bytes SKIP_MERGING_COMPACTION_KEY = + new Bytes(Bytes.toBytes(SKIP_MERGING_COMPACTION)); + /** * Used by HBase Shell interface to access this metadata attribute which denotes if the table is * split enabled. @@ -214,6 +223,12 @@ public class TableDescriptorBuilder { */ public static final boolean DEFAULT_MERGE_ENABLED = true; + /** + * Constant that denotes whether the table compaction only remove expired file, skipping merging + * file by default + */ + public static final boolean DEFAULT_SKIP_MERGING_COMPACTION = false; + /** * Constant that denotes the maximum default size of the memstore in bytes after which the * contents are flushed to the store files. @@ -434,6 +449,12 @@ public TableDescriptorBuilder setCompactionEnabled(final boolean isEnable) { return this; } + public TableDescriptorBuilder + setSkipMergingCompaction(final boolean shouldSkipMergingCompaction) { + desc.setSkipMergingCompaction(shouldSkipMergingCompaction); + return this; + } + public TableDescriptorBuilder setSplitEnabled(final boolean isEnable) { desc.setSplitEnabled(isEnable); return this; @@ -795,6 +816,17 @@ public boolean isCompactionEnabled() { return getOrDefault(COMPACTION_ENABLED_KEY, Boolean::valueOf, DEFAULT_COMPACTION_ENABLED); } + /** + * Check if the compaction only remove expired file flag of the table is true. If flag is false + * then do normal compactions. + * @return true if table compaction only remove expired file, skipping merge files. + */ + @Override + public boolean shouldSkipMergingCompaction() { + return getOrDefault(SKIP_MERGING_COMPACTION_KEY, Boolean::valueOf, + DEFAULT_SKIP_MERGING_COMPACTION); + } + /** * Setting the table compaction enable flag. * @param isEnable True if enable compaction. @@ -804,6 +836,17 @@ public ModifyableTableDescriptor setCompactionEnabled(final boolean isEnable) { return setValue(COMPACTION_ENABLED_KEY, Boolean.toString(isEnable)); } + /** + * Setting the table compaction only remove expired file, skipping merge files flag. + * @param shouldSkipMergingCompaction True if table compaction only remove expired file, + * skipping merge files. + * @return the modifyable TD + */ + public ModifyableTableDescriptor + setSkipMergingCompaction(final boolean shouldSkipMergingCompaction) { + return setValue(SKIP_MERGING_COMPACTION_KEY, Boolean.toString(shouldSkipMergingCompaction)); + } + /** * Check if the split enable flag of the table is true. If flag is false then no split will be * done. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HStore.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HStore.java index 3c879dbdb730..73ac504b8370 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HStore.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HStore.java @@ -138,6 +138,8 @@ public class HStore public static final String DEFAULT_BLOCK_STORAGE_POLICY = "NONE"; public static final int DEFAULT_COMPACTCHECKER_INTERVAL_MULTIPLIER = 1000; public static final int DEFAULT_BLOCKING_STOREFILE_COUNT = 16; + public static final String DELETE_EXPIRED_STOREFILE_KEY = "hbase.store.delete.expired.storefile"; + public static final Boolean DEFAULT_DELETE_EXPIRED_STOREFILE = true; // HBASE-24428 : Update compaction priority for recently split daughter regions // so as to prioritize their compaction. @@ -1453,6 +1455,15 @@ public Optional requestCompaction(int priority, // Before we do compaction, try to get rid of unneeded files to simplify things. removeUnneededFiles(); + if (this.region.getTableDescriptor().shouldSkipMergingCompaction()) { + if (!conf.getBoolean(DELETE_EXPIRED_STOREFILE_KEY, DEFAULT_DELETE_EXPIRED_STOREFILE)) { + LOG.info("Since config 'hbase.store.delete.expired.storefile' is set to false, ignoring " + + "SKIP_MERGING_COMPACTION set at table level"); + } else { + return Optional.empty(); + } + } + final CompactionContext compaction = storeEngine.createCompaction(); CompactionRequestImpl request = null; this.storeEngine.readLock(); @@ -1555,7 +1566,7 @@ private void addToCompactingFiles(Collection filesToAdd) { } private void removeUnneededFiles() throws IOException { - if (!conf.getBoolean("hbase.store.delete.expired.storefile", true)) { + if (!conf.getBoolean(DELETE_EXPIRED_STOREFILE_KEY, DEFAULT_DELETE_EXPIRED_STOREFILE)) { return; } if (getColumnFamilyDescriptor().getMinVersions() > 0) {