This is an automated email from the ASF dual-hosted git repository.

wchevreuil pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/master by this push:
     new 3cb15c6d516 HBASE-30330 NPE on 
CustomDateTieredCompactionPolicy.shouldPerformMajorCompaction (#8548)
3cb15c6d516 is described below

commit 3cb15c6d5168816479a13520e035b8b64256fa7d
Author: Wellington Ramos Chevreuil <[email protected]>
AuthorDate: Wed Aug 19 10:57:34 2026 +0100

    HBASE-30330 NPE on 
CustomDateTieredCompactionPolicy.shouldPerformMajorCompaction (#8548)
    
    Signed-off-by: Tak Lon (Stephen) Wu <[email protected]>
---
 .../CustomDateTieredCompactionPolicy.java          |  6 ++++
 .../compactions/TestCustomCellTieredCompactor.java | 39 ++++++++++++++++++++++
 2 files changed, 45 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 dcc97c63d02..8c3ecf076d6 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
@@ -129,6 +129,12 @@ public class CustomDateTieredCompactionPolicy extends 
DateTieredCompactionPolicy
           return true;
         }
         byte[] timeRangeBytes = f.getMetadataValue(CUSTOM_TIERING_TIME_RANGE);
+        // this means this file has not been major compacted by manually 
triggered compaction at
+        // the time of enabling Custom Time Based Priority, so it needs 
compaction to have its rows
+        // separated according to the cutOffTimestamp.
+        if (timeRangeBytes == null) {
+          return true;
+        }
         TimeRangeTracker timeRangeTracker = 
TimeRangeTracker.parseFrom(timeRangeBytes);
         if (timeRangeTracker.getMin() < cutOffTimestamp) {
           if (timeRangeTracker.getMax() > cutOffTimestamp) {
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCustomCellTieredCompactor.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCustomCellTieredCompactor.java
index 5b6b0dbaf2a..e8d55a5a673 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCustomCellTieredCompactor.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCustomCellTieredCompactor.java
@@ -17,6 +17,7 @@
  */
 package org.apache.hadoop.hbase.regionserver.compactions;
 
+import static org.apache.hadoop.hbase.HConstants.MAJOR_COMPACTION_PERIOD;
 import static 
org.apache.hadoop.hbase.regionserver.CustomTieringMultiFileWriter.CUSTOM_TIERING_TIME_RANGE;
 import static 
org.apache.hadoop.hbase.regionserver.compactions.CustomCellTieringValueProvider.TIERING_CELL_QUALIFIER;
 import static 
org.apache.hadoop.hbase.regionserver.compactions.CustomTieredCompactor.TIERING_VALUE_PROVIDER;
@@ -24,6 +25,8 @@ import static 
org.apache.hadoop.hbase.regionserver.compactions.RowKeyDateTiering
 import static 
org.apache.hadoop.hbase.regionserver.compactions.RowKeyDateTieringValueProvider.TIERING_KEY_DATE_PATTERN;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
@@ -41,6 +44,8 @@ import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.Table;
 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
 import org.apache.hadoop.hbase.regionserver.CustomTieredStoreEngine;
+import org.apache.hadoop.hbase.regionserver.HStore;
+import org.apache.hadoop.hbase.regionserver.HStoreFile;
 import org.apache.hadoop.hbase.regionserver.TimeRangeTracker;
 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
@@ -64,6 +69,7 @@ public class TestCustomCellTieredCompactor {
   public void setUp() throws Exception {
     utility = new HBaseTestingUtil();
     
utility.getConfiguration().setInt("hbase.hfile.compaction.discharger.interval", 
10);
+    utility.getConfiguration().setLong(MAJOR_COMPACTION_PERIOD, 10L);
     utility.startMiniCluster();
   }
 
@@ -316,4 +322,37 @@ public class TestCustomCellTieredCompactor {
         }
       });
   }
+
+  @Test
+  public void testShouldPerformMajorCompactionWhenTimeRangeMetadataIsNull() 
throws Exception {
+    ColumnFamilyDescriptorBuilder clmBuilder = 
ColumnFamilyDescriptorBuilder.newBuilder(FAMILY);
+    clmBuilder.setValue("hbase.hstore.engine.class", 
CustomTieredStoreEngine.class.getName());
+    clmBuilder.setValue(TIERING_CELL_QUALIFIER, "date");
+    TableName tableName = 
TableName.valueOf("testShouldCompactWhenNoTimeRangeMetadata");
+    TableDescriptorBuilder tblBuilder = 
TableDescriptorBuilder.newBuilder(tableName);
+    tblBuilder.setColumnFamily(clmBuilder.build());
+    utility.getAdmin().createTable(tblBuilder.build());
+    utility.waitTableAvailable(tableName);
+    Connection connection = utility.getConnection();
+    Table table = connection.getTable(tableName);
+    long recordTime = System.currentTimeMillis();
+    // Write data and flush to create store files without 
CUSTOM_TIERING_TIME_RANGE metadata
+    for (int i = 0; i < 2; i++) {
+      Put put = new Put(Bytes.toBytes(i));
+      put.addColumn(FAMILY, Bytes.toBytes("val"), Bytes.toBytes("v" + i));
+      put.addColumn(FAMILY, Bytes.toBytes("date"), Bytes.toBytes(recordTime));
+      table.put(put);
+      utility.flush(tableName);
+    }
+    table.close();
+
+    HStore store =
+      (HStore) 
utility.getMiniHBaseCluster().getRegions(tableName).get(0).getStore(FAMILY);
+    // Verify that flushed files do not have CUSTOM_TIERING_TIME_RANGE metadata
+    for (HStoreFile sf : store.getStorefiles()) {
+      assertNull(sf.getMetadataValue(CUSTOM_TIERING_TIME_RANGE));
+    }
+    // shouldPerformMajorCompaction must return true due to null timeRangeBytes
+    assertTrue(store.shouldPerformMajorCompaction());
+  }
 }

Reply via email to