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

lupeng pushed a commit to branch branch-2.5
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2.5 by this push:
     new 52b991381d9 HBASE-29296 Missing critical snapshot expiration checks 
(#7195)
52b991381d9 is described below

commit 52b991381d905634187c84ddacfe3d0dfca35fb7
Author: Dimas Shidqi Parikesit <[email protected]>
AuthorDate: Sat Aug 16 11:54:57 2025 -0400

    HBASE-29296 Missing critical snapshot expiration checks (#7195)
    
    Signed-off-by: Peng Lu <[email protected]>
---
 .../hbase/master/snapshot/TakeSnapshotHandler.java      | 10 ++++++++++
 .../hbase/client/TestSnapshotWithTTLFromClient.java     |  8 ++++----
 .../hbase/master/snapshot/TestTakeSnapshotHandler.java  | 17 +++++++++++++++++
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java
index e51321f3273..f967beec892 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java
@@ -50,7 +50,9 @@ import org.apache.hadoop.hbase.procedure2.LockType;
 import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
 import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
+import org.apache.hadoop.hbase.snapshot.SnapshotTTLExpiredException;
 import org.apache.hadoop.hbase.util.CommonFSUtils;
+import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.zookeeper.KeeperException;
@@ -238,6 +240,14 @@ public abstract class TakeSnapshotHandler extends 
EventHandler
       status.setStatus("Verifying snapshot: " + snapshot.getName());
       verifier.verifySnapshot(this.workingDir, serverNames);
 
+      // HBASE-29296 check snapshot is not expired
+      if (
+        SnapshotDescriptionUtils.isExpiredSnapshot(snapshot.getTtl(), 
snapshot.getCreationTime(),
+          EnvironmentEdgeManager.currentTime())
+      ) {
+        throw new 
SnapshotTTLExpiredException(ProtobufUtil.createSnapshotDesc(snapshot));
+      }
+
       // complete the snapshot, atomically moving from tmp to .snapshot dir.
       SnapshotDescriptionUtils.completeSnapshot(this.snapshotDir, 
this.workingDir, this.rootFs,
         this.workingDirFs, this.conf);
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotWithTTLFromClient.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotWithTTLFromClient.java
index 4309b922b8f..9713569e406 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotWithTTLFromClient.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotWithTTLFromClient.java
@@ -143,7 +143,7 @@ public class TestSnapshotWithTTLFromClient {
     assertTrue(UTIL.getAdmin().tableExists(TABLE_NAME));
 
     // create snapshot fo given table with specified ttl
-    createSnapshotWithTTL(TABLE_NAME, snapshotName, 1);
+    createSnapshotWithTTL(TABLE_NAME, snapshotName, 5);
     Admin admin = UTIL.getAdmin();
 
     // Disable and drop table
@@ -152,7 +152,7 @@ public class TestSnapshotWithTTLFromClient {
     assertFalse(UTIL.getAdmin().tableExists(TABLE_NAME));
 
     // Sleep so that TTL may expire
-    Threads.sleep(2000);
+    Threads.sleep(10000);
 
     // restore snapshot which has expired
     try {
@@ -192,13 +192,13 @@ public class TestSnapshotWithTTLFromClient {
     assertTrue(UTIL.getAdmin().tableExists(TABLE_NAME));
 
     // create snapshot fo given table with specified ttl
-    createSnapshotWithTTL(TABLE_NAME, snapshotName, 1);
+    createSnapshotWithTTL(TABLE_NAME, snapshotName, 5);
     Admin admin = UTIL.getAdmin();
 
     assertTrue(UTIL.getAdmin().tableExists(TABLE_NAME));
 
     // Sleep so that TTL may expire
-    Threads.sleep(2000);
+    Threads.sleep(10000);
 
     // clone snapshot which has expired
     try {
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/snapshot/TestTakeSnapshotHandler.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/snapshot/TestTakeSnapshotHandler.java
index e9d3b9784d6..edf232394ed 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/snapshot/TestTakeSnapshotHandler.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/snapshot/TestTakeSnapshotHandler.java
@@ -18,6 +18,8 @@
 package org.apache.hadoop.hbase.master.snapshot;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -29,6 +31,8 @@ import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.client.Table;
 import org.apache.hadoop.hbase.client.TableDescriptor;
 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
+import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
+import org.apache.hadoop.hbase.snapshot.SnapshotTTLExpiredException;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.junit.After;
@@ -100,6 +104,19 @@ public class TestTakeSnapshotHandler {
     assertEquals(-1, UTIL.getAdmin().getDescriptor(cloned).getMaxFileSize());
   }
 
+  @Test
+  public void testSnapshotEarlyExpiration() throws Exception {
+    UTIL.startMiniCluster();
+    Map<String, Object> snapshotProps = new HashMap<>();
+    snapshotProps.put("TTL", 1L);
+    HBaseSnapshotException hBaseSnapshotException = 
assertThrows(HBaseSnapshotException.class,
+      () -> createTableInsertDataAndTakeSnapshot(snapshotProps));
+    assertTrue(
+      
hBaseSnapshotException.toString().contains(SnapshotTTLExpiredException.class.getName()));
+    assertTrue(hBaseSnapshotException.getMessage()
+      .contains("TTL for snapshot 'snaptestSnapshotEarlyExpiration' has 
already expired"));
+  }
+
   @After
   public void shutdown() throws Exception {
     UTIL.shutdownMiniCluster();

Reply via email to