Skip to content

Commit d1fc87e

Browse files
authored
HBASE-28502 Cleanup old backup manifest logic (#5871)
In older versions of HBase's backup mechanism, a manifest was written per table being backed up. This was since refactored to one manifest per backup, but the manifest code was not updated. A concrete issue with the old code was that the manifest for full backups did not correctly list the tables included in the backup. Signed-off-by: Nick Dimiduk <ndimiduk@apache.org> Reviewed-by: Ray Mattingly <rmdmattingly@gmail.com>
1 parent ca34010 commit d1fc87e

File tree

8 files changed

+42
-97
lines changed

8 files changed

+42
-97
lines changed

hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/HBackupFileSystem.java

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818
package org.apache.hadoop.hbase.backup;
1919

2020
import java.io.IOException;
21-
import java.util.HashMap;
2221
import org.apache.hadoop.conf.Configuration;
2322
import org.apache.hadoop.fs.FileSystem;
2423
import org.apache.hadoop.fs.Path;
25-
import org.apache.hadoop.hbase.HConstants;
2624
import org.apache.hadoop.hbase.TableName;
2725
import org.apache.hadoop.hbase.backup.impl.BackupManifest;
2826
import org.apache.yetus.audience.InterfaceAudience;
@@ -44,8 +42,8 @@ private HBackupFileSystem() {
4442
}
4543

4644
/**
47-
* Given the backup root dir, backup id and the table name, return the backup image location,
48-
* which is also where the backup manifest file is. return value look like:
45+
* Given the backup root dir, backup id and the table name, return the backup image location.
46+
* Return value look like:
4947
* "hdfs://backup.hbase.org:9000/user/biadmin/backup/backup_1396650096738/default/t1_dn/", where
5048
* "hdfs://backup.hbase.org:9000/user/biadmin/backup" is a backup root directory
5149
* @param backupRootDir backup root directory
@@ -79,11 +77,6 @@ public static Path getBackupTmpDirPathForBackupId(String backupRoot, String back
7977
return new Path(getBackupTmpDirPath(backupRoot), backupId);
8078
}
8179

82-
public static String getTableBackupDataDir(String backupRootDir, String backupId,
83-
TableName tableName) {
84-
return getTableBackupDir(backupRootDir, backupId, tableName) + Path.SEPARATOR + "data";
85-
}
86-
8780
public static Path getBackupPath(String backupRootDir, String backupId) {
8881
return new Path(backupRootDir + Path.SEPARATOR + backupId);
8982
}
@@ -102,24 +95,6 @@ public static Path getTableBackupPath(TableName tableName, Path backupRootPath,
10295
return new Path(getTableBackupDir(backupRootPath.toString(), backupId, tableName));
10396
}
10497

105-
/**
106-
* Given the backup root dir and the backup id, return the log file location for an incremental
107-
* backup.
108-
* @param backupRootDir backup root directory
109-
* @param backupId backup id
110-
* @return logBackupDir: ".../user/biadmin/backup/WALs/backup_1396650096738"
111-
*/
112-
public static String getLogBackupDir(String backupRootDir, String backupId) {
113-
return backupRootDir + Path.SEPARATOR + backupId + Path.SEPARATOR
114-
+ HConstants.HREGION_LOGDIR_NAME;
115-
}
116-
117-
public static Path getLogBackupPath(String backupRootDir, String backupId) {
118-
return new Path(getLogBackupDir(backupRootDir, backupId));
119-
}
120-
121-
// TODO we do not keep WAL files anymore
122-
// Move manifest file to other place
12398
private static Path getManifestPath(Configuration conf, Path backupRootPath, String backupId)
12499
throws IOException {
125100
FileSystem fs = backupRootPath.getFileSystem(conf);
@@ -140,19 +115,4 @@ public static BackupManifest getManifest(Configuration conf, Path backupRootPath
140115
new BackupManifest(conf, getManifestPath(conf, backupRootPath, backupId));
141116
return manifest;
142117
}
143-
144-
/**
145-
* Check whether the backup image path and there is manifest file in the path.
146-
* @param backupManifestMap If all the manifests are found, then they are put into this map
147-
* @param tableArray the tables involved
148-
* @throws IOException exception
149-
*/
150-
public static void checkImageManifestExist(HashMap<TableName, BackupManifest> backupManifestMap,
151-
TableName[] tableArray, Configuration conf, Path backupRootPath, String backupId)
152-
throws IOException {
153-
for (TableName tableName : tableArray) {
154-
BackupManifest manifest = getManifest(conf, backupRootPath, backupId);
155-
backupManifestMap.put(tableName, manifest);
156-
}
157-
}
158118
}

hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupAdminImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.io.IOException;
2121
import java.util.ArrayList;
22+
import java.util.Arrays;
2223
import java.util.Collections;
2324
import java.util.HashMap;
2425
import java.util.HashSet;
@@ -498,16 +499,15 @@ private String[] toStringArray(TableName[] list) {
498499
@Override
499500
public void restore(RestoreRequest request) throws IOException {
500501
if (request.isCheck()) {
501-
HashMap<TableName, BackupManifest> backupManifestMap = new HashMap<>();
502502
// check and load backup image manifest for the tables
503503
Path rootPath = new Path(request.getBackupRootDir());
504504
String backupId = request.getBackupId();
505505
TableName[] sTableArray = request.getFromTables();
506-
HBackupFileSystem.checkImageManifestExist(backupManifestMap, sTableArray,
507-
conn.getConfiguration(), rootPath, backupId);
506+
BackupManifest manifest =
507+
HBackupFileSystem.getManifest(conn.getConfiguration(), rootPath, backupId);
508508

509509
// Check and validate the backup image and its dependencies
510-
if (BackupUtils.validate(backupManifestMap, conn.getConfiguration())) {
510+
if (BackupUtils.validate(Arrays.asList(sTableArray), manifest, conn.getConfiguration())) {
511511
LOG.info(CHECK_OK);
512512
} else {
513513
LOG.error(CHECK_FAILED);

hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/BackupManifest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ public List<TableName> getTableList() {
465465
}
466466

467467
/**
468-
* TODO: fix it. Persist the manifest file.
468+
* Persist the manifest file.
469469
* @throws BackupException if an error occurred while storing the manifest file.
470470
*/
471471
public void store(Configuration conf) throws BackupException {

hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/RestoreTablesClient.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import java.io.IOException;
2323
import java.util.ArrayList;
24-
import java.util.HashMap;
2524
import java.util.List;
2625
import java.util.TreeSet;
2726
import org.apache.commons.lang3.StringUtils;
@@ -204,19 +203,17 @@ private List<Path> getFilesRecursively(String fileBackupDir)
204203

205204
/**
206205
* Restore operation. Stage 2: resolved Backup Image dependency
207-
* @param backupManifestMap : tableName, Manifest
208-
* @param sTableArray The array of tables to be restored
209-
* @param tTableArray The array of mapping tables to restore to
206+
* @param sTableArray The array of tables to be restored
207+
* @param tTableArray The array of mapping tables to restore to
210208
* @throws IOException exception
211209
*/
212-
private void restore(HashMap<TableName, BackupManifest> backupManifestMap,
213-
TableName[] sTableArray, TableName[] tTableArray, boolean isOverwrite) throws IOException {
210+
private void restore(BackupManifest manifest, TableName[] sTableArray, TableName[] tTableArray,
211+
boolean isOverwrite) throws IOException {
214212
TreeSet<BackupImage> restoreImageSet = new TreeSet<>();
215213

216214
for (int i = 0; i < sTableArray.length; i++) {
217215
TableName table = sTableArray[i];
218216

219-
BackupManifest manifest = backupManifestMap.get(table);
220217
// Get the image list of this backup for restore in time order from old
221218
// to new.
222219
List<BackupImage> list = new ArrayList<>();
@@ -256,12 +253,10 @@ public void execute() throws IOException {
256253
checkTargetTables(tTableArray, isOverwrite);
257254

258255
// case RESTORE_IMAGES:
259-
HashMap<TableName, BackupManifest> backupManifestMap = new HashMap<>();
260256
// check and load backup image manifest for the tables
261257
Path rootPath = new Path(backupRootDir);
262-
HBackupFileSystem.checkImageManifestExist(backupManifestMap, sTableArray, conf, rootPath,
263-
backupId);
258+
BackupManifest manifest = HBackupFileSystem.getManifest(conf, rootPath, backupId);
264259

265-
restore(backupManifestMap, sTableArray, tTableArray, isOverwrite);
260+
restore(manifest, sTableArray, tTableArray, isOverwrite);
266261
}
267262
}

hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/TableBackupClient.java

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.io.IOException;
2121
import java.util.ArrayList;
22-
import java.util.HashMap;
2322
import java.util.List;
2423
import java.util.Map;
2524
import org.apache.hadoop.conf.Configuration;
@@ -268,7 +267,7 @@ public static void cleanupAndRestoreBackupSystem(Connection conn, BackupInfo bac
268267
}
269268

270269
/**
271-
* Add manifest for the current backup. The manifest is stored within the table backup directory.
270+
* Creates a manifest based on the provided info, and store it in the backup-specific directory.
272271
* @param backupInfo The current backup info
273272
* @throws IOException exception
274273
*/
@@ -277,43 +276,16 @@ protected void addManifest(BackupInfo backupInfo, BackupManager backupManager, B
277276
// set the overall backup phase : store manifest
278277
backupInfo.setPhase(BackupPhase.STORE_MANIFEST);
279278

280-
BackupManifest manifest;
281-
282-
// Since we have each table's backup in its own directory structure,
283-
// we'll store its manifest with the table directory.
284-
for (TableName table : backupInfo.getTables()) {
285-
manifest = new BackupManifest(backupInfo, table);
286-
ArrayList<BackupImage> ancestors = backupManager.getAncestors(backupInfo, table);
287-
for (BackupImage image : ancestors) {
288-
manifest.addDependentImage(image);
289-
}
290-
291-
if (type == BackupType.INCREMENTAL) {
292-
// We'll store the log timestamps for this table only in its manifest.
293-
Map<TableName, Map<String, Long>> tableTimestampMap = new HashMap<>();
294-
tableTimestampMap.put(table, backupInfo.getIncrTimestampMap().get(table));
295-
manifest.setIncrTimestampMap(tableTimestampMap);
296-
ArrayList<BackupImage> ancestorss = backupManager.getAncestors(backupInfo);
297-
for (BackupImage image : ancestorss) {
298-
manifest.addDependentImage(image);
299-
}
300-
}
301-
manifest.store(conf);
302-
}
303-
304-
// For incremental backup, we store a overall manifest in
305-
// <backup-root-dir>/WALs/<backup-id>
306-
// This is used when created the next incremental backup
279+
BackupManifest manifest = new BackupManifest(backupInfo);
307280
if (type == BackupType.INCREMENTAL) {
308-
manifest = new BackupManifest(backupInfo);
309281
// set the table region server start and end timestamps for incremental backup
310282
manifest.setIncrTimestampMap(backupInfo.getIncrTimestampMap());
311-
ArrayList<BackupImage> ancestors = backupManager.getAncestors(backupInfo);
312-
for (BackupImage image : ancestors) {
313-
manifest.addDependentImage(image);
314-
}
315-
manifest.store(conf);
316283
}
284+
ArrayList<BackupImage> ancestors = backupManager.getAncestors(backupInfo);
285+
for (BackupImage image : ancestors) {
286+
manifest.addDependentImage(image);
287+
}
288+
manifest.store(conf);
317289
}
318290

319291
/**

hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/util/BackupUtils.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -664,15 +664,14 @@ public static RestoreRequest createRestoreRequest(String backupRootDir, String b
664664
return request;
665665
}
666666

667-
public static boolean validate(HashMap<TableName, BackupManifest> backupManifestMap,
667+
public static boolean validate(List<TableName> tables, BackupManifest backupManifest,
668668
Configuration conf) throws IOException {
669669
boolean isValid = true;
670670

671-
for (Entry<TableName, BackupManifest> manifestEntry : backupManifestMap.entrySet()) {
672-
TableName table = manifestEntry.getKey();
671+
for (TableName table : tables) {
673672
TreeSet<BackupImage> imageSet = new TreeSet<>();
674673

675-
ArrayList<BackupImage> depList = manifestEntry.getValue().getDependentListByTable(table);
674+
ArrayList<BackupImage> depList = backupManifest.getDependentListByTable(table);
676675
if (depList != null && !depList.isEmpty()) {
677676
imageSet.addAll(depList);
678677
}

hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestFullBackup.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
*/
1818
package org.apache.hadoop.hbase.backup;
1919

20+
import static org.junit.Assert.assertEquals;
2021
import static org.junit.Assert.assertTrue;
2122

23+
import java.util.HashSet;
2224
import java.util.List;
25+
import org.apache.hadoop.fs.Path;
2326
import org.apache.hadoop.hbase.HBaseClassTestRule;
27+
import org.apache.hadoop.hbase.backup.impl.BackupManifest;
2428
import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
2529
import org.apache.hadoop.hbase.testclassification.LargeTests;
2630
import org.apache.hadoop.util.ToolRunner;
@@ -30,6 +34,8 @@
3034
import org.slf4j.Logger;
3135
import org.slf4j.LoggerFactory;
3236

37+
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
38+
3339
@Category(LargeTests.class)
3440
public class TestFullBackup extends TestBackupBase {
3541

@@ -56,6 +62,11 @@ public void testFullBackupMultipleCommand() throws Exception {
5662
String backupId = data.getBackupId();
5763
assertTrue(checkSucceeded(backupId));
5864
}
65+
66+
BackupInfo newestBackup = backups.get(0);
67+
BackupManifest manifest =
68+
HBackupFileSystem.getManifest(conf1, new Path(BACKUP_ROOT_DIR), newestBackup.getBackupId());
69+
assertEquals(Sets.newHashSet(table1, table2), new HashSet<>(manifest.getTableList()));
5970
}
6071
LOG.info("backup complete");
6172
}

hbase-backup/src/test/java/org/apache/hadoop/hbase/backup/TestIncrementalBackup.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@
1717
*/
1818
package org.apache.hadoop.hbase.backup;
1919

20+
import static org.junit.Assert.assertEquals;
2021
import static org.junit.Assert.assertTrue;
2122

2223
import java.util.ArrayList;
2324
import java.util.Collection;
25+
import java.util.HashSet;
2426
import java.util.List;
27+
import org.apache.hadoop.fs.Path;
2528
import org.apache.hadoop.hbase.HBaseClassTestRule;
2629
import org.apache.hadoop.hbase.HBaseTestingUtil;
2730
import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
2831
import org.apache.hadoop.hbase.TableName;
2932
import org.apache.hadoop.hbase.backup.impl.BackupAdminImpl;
33+
import org.apache.hadoop.hbase.backup.impl.BackupManifest;
3034
import org.apache.hadoop.hbase.backup.util.BackupUtils;
3135
import org.apache.hadoop.hbase.client.Admin;
3236
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
@@ -50,6 +54,7 @@
5054
import org.slf4j.LoggerFactory;
5155

5256
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
57+
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
5358

5459
@Category(LargeTests.class)
5560
@RunWith(Parameterized.class)
@@ -148,6 +153,9 @@ public void TestIncBackupRestore() throws Exception {
148153
request = createBackupRequest(BackupType.INCREMENTAL, tables, BACKUP_ROOT_DIR);
149154
String backupIdIncMultiple = client.backupTables(request);
150155
assertTrue(checkSucceeded(backupIdIncMultiple));
156+
BackupManifest manifest =
157+
HBackupFileSystem.getManifest(conf1, new Path(BACKUP_ROOT_DIR), backupIdIncMultiple);
158+
assertEquals(Sets.newHashSet(table1, table2), new HashSet<>(manifest.getTableList()));
151159

152160
// add column family f2 to table1
153161
// drop column family f3

0 commit comments

Comments
 (0)