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

taklwu 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 96922fc01c5 HBASE-29984 Support separate old WAL directories in backup 
(#8512)
96922fc01c5 is described below

commit 96922fc01c5c9ff712baf793eff7ad7674477635
Author: Ma Zhengxuan <[email protected]>
AuthorDate: Wed Aug 12 00:22:46 2026 +0800

    HBASE-29984 Support separate old WAL directories in backup (#8512)
    
    Signed-off-by: Tak Lon (Stephen) Wu <[email protected]>
    Co-authored-by: mazhengxuan <[email protected]>
---
 .../backup/impl/IncrementalBackupManager.java      |   8 +-
 .../hadoop/hbase/backup/util/BackupUtils.java      |   4 +
 .../hadoop/hbase/backup/TestBackupUtils.java       |   5 +
 .../hbase/backup/TestIncrementalBackupManager.java | 104 +++++++++++++++++++++
 4 files changed, 117 insertions(+), 4 deletions(-)

diff --git 
a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/IncrementalBackupManager.java
 
b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/IncrementalBackupManager.java
index 5f48bfc39ad..18be4c4f94a 100644
--- 
a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/IncrementalBackupManager.java
+++ 
b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/IncrementalBackupManager.java
@@ -184,10 +184,10 @@ public class IncrementalBackupManager extends 
BackupManager {
     }
 
     // Include the .oldlogs files too.
-    FileStatus[] oldlogs = fs.listStatus(oldLogDir);
-    for (FileStatus oldlog : oldlogs) {
-      p = oldlog.getPath();
-      currentLogFile = p.toString();
+    List<String> oldlogs = BackupUtils.getFiles(fs, oldLogDir, new 
ArrayList<>(), path -> true);
+    for (String oldlog : oldlogs) {
+      p = new Path(oldlog);
+      currentLogFile = oldlog;
       if (AbstractFSWALProvider.isMetaFile(p)) {
         if (LOG.isDebugEnabled()) {
           LOG.debug("Skip .meta log file: " + currentLogFile);
diff --git 
a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/BackupUtils.java
 
b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/BackupUtils.java
index 138426d9079..b094b35e8e5 100644
--- 
a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/BackupUtils.java
+++ 
b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/BackupUtils.java
@@ -332,6 +332,10 @@ public final class BackupUtils {
     if (p.getName().endsWith(MasterRegionFactory.ARCHIVED_WAL_SUFFIX)) {
       return null;
     }
+    Path parent = p.getParent();
+    if (parent != null && ServerName.isFullServerName(parent.getName())) {
+      return ServerName.valueOf(parent.getName()).getAddress().toString();
+    }
     try {
       String urlDecodedName = URLDecoder.decode(p.getName(), "UTF8");
       Iterable<String> nameSplitsOnComma = 
Splitter.on(",").split(urlDecodedName);
diff --git 
a/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestBackupUtils.java
 
b/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestBackupUtils.java
index cf69476270c..07dec45b694 100644
--- 
a/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestBackupUtils.java
+++ 
b/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestBackupUtils.java
@@ -111,6 +111,11 @@ public class TestBackupUtils {
           + "regiongroup-0" + BackupUtils.LOGNAME_SEPARATOR + 
EnvironmentEdgeManager.currentTime());
       assertEquals(host + Addressing.HOSTNAME_PORT_SEPARATOR + port,
         BackupUtils.parseHostFromOldLog(testOldWalWithRegionGroupingPath));
+
+      Path testOldWalInServerDirPath = new Path(new Path(oldLogDir, 
serverName.toString()),
+        "wal" + BackupUtils.LOGNAME_SEPARATOR + 
EnvironmentEdgeManager.currentTime());
+      assertEquals(host + Addressing.HOSTNAME_PORT_SEPARATOR + port,
+        BackupUtils.parseHostFromOldLog(testOldWalInServerDirPath));
     }
 
   }
diff --git 
a/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestIncrementalBackupManager.java
 
b/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestIncrementalBackupManager.java
new file mode 100644
index 00000000000..6ea46e96202
--- /dev/null
+++ 
b/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestIncrementalBackupManager.java
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+package org.apache.hadoop.hbase.backup;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.HBaseTestingUtil;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.backup.impl.BackupAdminImpl;
+import org.apache.hadoop.hbase.backup.impl.IncrementalBackupManager;
+import org.apache.hadoop.hbase.backup.util.BackupUtils;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.testclassification.LargeTests;
+import org.apache.hadoop.hbase.util.CommonFSUtils;
+import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
+import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+@Tag(LargeTests.TAG)
+public class TestIncrementalBackupManager extends TestBackupBase {
+
+  @BeforeAll
+  public static void setUp() throws Exception {
+    TEST_UTIL = new HBaseTestingUtil();
+    conf1 = TEST_UTIL.getConfiguration();
+    conf1.setBoolean(AbstractFSWALProvider.SEPARATE_OLDLOGDIR, true);
+    autoRestoreOnFailure = true;
+    useSecondCluster = false;
+    setUpHelper();
+  }
+
+  @Test
+  public void testCollectWALFilesFromRegionServerDirectories() throws 
Exception {
+    testCollectWALFiles(true);
+  }
+
+  @Test
+  public void testCollectWALFilesFromFlatOldWALDirectory() throws Exception {
+    testCollectWALFiles(false);
+  }
+
+  private void testCollectWALFiles(boolean separateOldLogDir) throws Exception 
{
+    Configuration testConf = new Configuration(conf1);
+    testConf.setBoolean(AbstractFSWALProvider.SEPARATE_OLDLOGDIR, 
separateOldLogDir);
+    List<TableName> tables = List.of(table1);
+    try (Connection conn = ConnectionFactory.createConnection(testConf);
+      BackupAdminImpl backupAdmin = new BackupAdminImpl(conn)) {
+      String fullBackupId =
+        backupAdmin.backupTables(createBackupRequest(BackupType.FULL, tables, 
BACKUP_ROOT_DIR));
+      assertTrue(checkSucceeded(fullBackupId));
+
+      try (IncrementalBackupManager manager = new 
IncrementalBackupManager(conn, testConf)) {
+        BackupInfo backupInfo = manager.createBackupInfo("backup_test", 
BackupType.INCREMENTAL,
+          tables, BACKUP_ROOT_DIR, -1, -1, false);
+        Map<String, Long> previousTimestamps =
+          BackupUtils.getRSLogTimestampMins(manager.readLogTimestampMap());
+        ServerName serverName = 
TEST_UTIL.getMiniHBaseCluster().getRegionServer(0).getServerName();
+        Long previousTimestamp = 
previousTimestamps.get(serverName.getAddress().toString());
+        assertNotNull(previousTimestamp);
+
+        TEST_UTIL.waitFor(30_000,
+          () -> EnvironmentEdgeManager.currentTime() > previousTimestamp + 1);
+        Path walRootDir = CommonFSUtils.getWALRootDir(conf1);
+        Path archiveDir = new Path(walRootDir,
+          AbstractFSWALProvider.getWALArchiveDirectoryName(testConf, 
serverName.toString()));
+        String walName = (separateOldLogDir ? "wal" : serverName.toString())
+          + BackupUtils.LOGNAME_SEPARATOR + (previousTimestamp + 1);
+        Path archivedWAL = new Path(archiveDir, walName);
+        FileSystem fs = walRootDir.getFileSystem(conf1);
+        fs.mkdirs(archiveDir);
+        fs.create(archivedWAL).close();
+
+        manager.getIncrBackupLogFileMap();
+
+        
assertTrue(backupInfo.getIncrBackupFileList().contains(archivedWAL.toString()));
+      }
+    }
+  }
+}

Reply via email to