From e606b18a0c17be3a4e33fda28f0024cd8b463f5a Mon Sep 17 00:00:00 2001 From: Jeremy Schoemaker Date: Tue, 25 Aug 2026 19:05:52 -0500 Subject: [PATCH 1/2] fix(hbase): handle missing CUSTOM_TIERING_TIME_RANGE in getCompactBoundariesForMajor Fix verified RED->GREEN. getCompactBoundariesForMajor silently drops files lacking CUSTOM_TIERING_TIME_RANGE at CustomDateTieredCompactionPolicy.java:72 --- .../compactions/CustomDateTieredCompactionPolicy.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java index 8c3ecf076d63..a44a93e3fb11 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java @@ -70,6 +70,7 @@ protected List getCompactBoundariesForMajor(Collection filesTo long now) { MutableLong min = new MutableLong(Long.MAX_VALUE); MutableLong max = new MutableLong(0); + boolean[] hasMissing = new boolean[1]; filesToCompact.forEach(f -> { byte[] timeRangeBytes = f.getMetadataValue(CUSTOM_TIERING_TIME_RANGE); long minCurrent = Long.MAX_VALUE; @@ -82,7 +83,10 @@ protected List getCompactBoundariesForMajor(Collection filesTo maxCurrent = timeRangeTracker.getMax(); } catch (IOException e) { LOG.warn("Got TIERING_CELL_TIME_RANGE info from file, but failed to parse it:", e); + hasMissing[0] = true; } + } else { + hasMissing[0] = true; } if (minCurrent < min.getValue()) { min.setValue(minCurrent); @@ -94,6 +98,10 @@ protected List getCompactBoundariesForMajor(Collection filesTo List boundaries = new ArrayList<>(); boundaries.add(Long.MIN_VALUE); + if (hasMissing[0]) { + boundaries.add(cutOffTimestamp); + return boundaries; + } if (min.getValue() < cutOffTimestamp) { boundaries.add(min.getValue()); if (max.getValue() > cutOffTimestamp) { From 7637d74e554c86328dc452ac26cb7f12f6098796 Mon Sep 17 00:00:00 2001 From: shoemoney Date: Thu, 27 Aug 2026 15:39:42 -0500 Subject: [PATCH 2/2] fix(hbase): simplify getCompactBoundariesForMajor to always offer the cutOffTimestamp boundary CustomTieringMultiFileWriter#append already routes each cell to its tier by comparing against the returned boundaries and skips committing a file for a tier that receives no data, so traversing filesToCompact to inspect CUSTOM_TIERING_TIME_RANGE is unnecessary. Always returning [MIN_VALUE, cutOffTimestamp] is simpler and does not miss the boundary when a file lacks the metadata. --- .../CustomDateTieredCompactionPolicy.java | 45 +++---------------- 1 file changed, 6 insertions(+), 39 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java index a44a93e3fb11..7d059e3c77dc 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CustomDateTieredCompactionPolicy.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.apache.commons.lang3.mutable.MutableLong; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HDFSBlocksDistribution; import org.apache.hadoop.hbase.regionserver.HStoreFile; @@ -68,46 +67,14 @@ public CustomDateTieredCompactionPolicy(Configuration conf, @Override protected List getCompactBoundariesForMajor(Collection filesToCompact, long now) { - MutableLong min = new MutableLong(Long.MAX_VALUE); - MutableLong max = new MutableLong(0); - boolean[] hasMissing = new boolean[1]; - filesToCompact.forEach(f -> { - byte[] timeRangeBytes = f.getMetadataValue(CUSTOM_TIERING_TIME_RANGE); - long minCurrent = Long.MAX_VALUE; - long maxCurrent = 0; - if (timeRangeBytes != null) { - try { - TimeRangeTracker timeRangeTracker = TimeRangeTracker.parseFrom(timeRangeBytes); - timeRangeTracker.getMin(); - minCurrent = timeRangeTracker.getMin(); - maxCurrent = timeRangeTracker.getMax(); - } catch (IOException e) { - LOG.warn("Got TIERING_CELL_TIME_RANGE info from file, but failed to parse it:", e); - hasMissing[0] = true; - } - } else { - hasMissing[0] = true; - } - if (minCurrent < min.getValue()) { - min.setValue(minCurrent); - } - if (maxCurrent > max.getValue()) { - max.setValue(maxCurrent); - } - }); - + // CustomTieringMultiFileWriter#append buckets each cell into its tier by comparing against + // these boundaries directly, and only commits a file for a tier that actually received data. + // There is no need to traverse filesToCompact to inspect CUSTOM_TIERING_TIME_RANGE here: + // always offering the cutOffTimestamp boundary is sufficient and avoids missing it when a + // file lacks that metadata. List boundaries = new ArrayList<>(); boundaries.add(Long.MIN_VALUE); - if (hasMissing[0]) { - boundaries.add(cutOffTimestamp); - return boundaries; - } - if (min.getValue() < cutOffTimestamp) { - boundaries.add(min.getValue()); - if (max.getValue() > cutOffTimestamp) { - boundaries.add(cutOffTimestamp); - } - } + boundaries.add(cutOffTimestamp); return boundaries; }