You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by bb...@apache.org on 2024/04/02 12:38:54 UTC
(hbase) branch master updated: HBASE-28460 Full backup restore failed on empty HFiles (#5782)
This is an automated email from the ASF dual-hosted git repository.
bbeaudreault 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 90639d75a58 HBASE-28460 Full backup restore failed on empty HFiles (#5782)
90639d75a58 is described below
commit 90639d75a588318571cbcc63fddf66ec2372c105
Author: DieterDP <90...@users.noreply.github.com>
AuthorDate: Tue Apr 2 14:38:48 2024 +0200
HBASE-28460 Full backup restore failed on empty HFiles (#5782)
Signed-off-by: Bryan Beaudreault <bb...@apache.org>
---
.../backup/mapreduce/MapReduceRestoreJob.java | 5 +--
.../hadoop/hbase/backup/util/RestoreTool.java | 14 ++++++--
.../hadoop/hbase/backup/TestFullRestore.java | 38 ++++++++++++++++++++++
3 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/mapreduce/MapReduceRestoreJob.java b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/mapreduce/MapReduceRestoreJob.java
index 5d654c0d85b..7a2fce4c418 100644
--- a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/mapreduce/MapReduceRestoreJob.java
+++ b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/mapreduce/MapReduceRestoreJob.java
@@ -87,10 +87,7 @@ public class MapReduceRestoreJob implements RestoreJob {
LOG.debug("Restoring HFiles from directory " + bulkOutputPath);
}
- if (loader.bulkLoad(newTableNames[i], bulkOutputPath).isEmpty()) {
- throw new IOException("Can not restore from backup directory " + dirs
- + " (check Hadoop and HBase logs). Bulk loader returns null");
- }
+ loader.bulkLoad(newTableNames[i], bulkOutputPath);
} else {
throw new IOException("Can not restore from backup directory " + dirs
+ " (check Hadoop/MR and HBase logs). Player return code =" + result);
diff --git a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/RestoreTool.java b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/RestoreTool.java
index 8ca80d1301f..ff4e2672f7a 100644
--- a/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/RestoreTool.java
+++ b/hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/RestoreTool.java
@@ -61,7 +61,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.Snapshot
*/
@InterfaceAudience.Private
public class RestoreTool {
- public static final Logger LOG = LoggerFactory.getLogger(BackupUtils.class);
+ public static final Logger LOG = LoggerFactory.getLogger(RestoreTool.class);
private final static long TABLE_AVAILABILITY_WAIT_TIME = 180000;
private final String[] ignoreDirs = { HConstants.RECOVERED_EDITS_DIR };
@@ -437,6 +437,10 @@ public class RestoreTool {
HFile.Reader reader = HFile.createReader(fs, hfile, conf);
final byte[] first, last;
try {
+ if (reader.getEntries() == 0) {
+ LOG.debug("Skipping hfile with 0 entries: " + hfile);
+ continue;
+ }
first = reader.getFirstRowKey().get();
last = reader.getLastRowKey().get();
LOG.debug("Trying to figure out region boundaries hfile=" + hfile + " first="
@@ -491,8 +495,12 @@ public class RestoreTool {
admin.createTable(htd);
} else {
keys = generateBoundaryKeys(regionDirList);
- // create table using table descriptor and region boundaries
- admin.createTable(htd, keys);
+ if (keys.length > 0) {
+ // create table using table descriptor and region boundaries
+ admin.createTable(htd, keys);
+ } else {
+ admin.createTable(htd);
+ }
}
} catch (NamespaceNotFoundException e) {
LOG.warn("There was no namespace and the same will be created");
diff --git a/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestFullRestore.java b/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestFullRestore.java
index 385a6b3c519..d16d7af7501 100644
--- a/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestFullRestore.java
+++ b/hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestFullRestore.java
@@ -27,6 +27,7 @@ import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.backup.util.BackupUtils;
import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.util.ToolRunner;
import org.junit.ClassRule;
@@ -71,6 +72,43 @@ public class TestFullRestore extends TestBackupBase {
hba.close();
}
+ @Test
+ public void testFullRestoreSingleWithRegion() throws Exception {
+ LOG.info("test full restore on a single table empty table that has a region");
+
+ // This test creates its own table so other tests are not affected (we adjust it in this test)
+ TableName tableName = TableName.valueOf("table-full-restore-single-region");
+ TEST_UTIL.createTable(tableName, famName);
+
+ Admin admin = TEST_UTIL.getAdmin();
+
+ // Add & remove data to ensure a region is active, but functionally empty
+ Table table = TEST_UTIL.getConnection().getTable(tableName);
+ loadTable(table);
+ admin.flush(tableName);
+ TEST_UTIL.deleteTableData(tableName);
+ admin.flush(tableName);
+
+ TEST_UTIL.compact(tableName, true);
+
+ List<TableName> tables = Lists.newArrayList(tableName);
+ String backupId = fullTableBackup(tables);
+ assertTrue(checkSucceeded(backupId));
+
+ LOG.info("backup complete");
+
+ TEST_UTIL.deleteTable(tableName);
+
+ TableName[] tableset = new TableName[] { tableName };
+ TableName[] tablemap = new TableName[] { tableName };
+ BackupAdmin client = getBackupAdmin();
+ client.restore(BackupUtils.createRestoreRequest(BACKUP_ROOT_DIR, backupId, false, tableset,
+ tablemap, false));
+ assertTrue(admin.tableExists(tableName));
+ TEST_UTIL.deleteTable(tableName);
+ admin.close();
+ }
+
@Test
public void testFullRestoreSingleCommand() throws Exception {
LOG.info("test full restore on a single table empty table: command-line");