HBASE-18887 After full backup passed on hdfs root and incremental failed, full backup cannot be cleaned (Vladimir Rodionov)

This commit is contained in:
tedyu 2017-09-28 10:20:48 -07:00
parent 6693f45faf
commit a71f62de02
3 changed files with 34 additions and 8 deletions

View File

@ -58,11 +58,11 @@ import org.apache.hadoop.hbase.backup.BackupRestoreConstants.BackupCommand;
import org.apache.hadoop.hbase.backup.BackupType; import org.apache.hadoop.hbase.backup.BackupType;
import org.apache.hadoop.hbase.backup.util.BackupSet; import org.apache.hadoop.hbase.backup.util.BackupSet;
import org.apache.hadoop.hbase.backup.util.BackupUtils; import org.apache.hadoop.hbase.backup.util.BackupUtils;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory; import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.shaded.com.google.common.collect.Lists; import org.apache.hadoop.hbase.shaded.com.google.common.collect.Lists;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.yetus.audience.InterfaceAudience;
/** /**
* General backup commands, options and usage messages * General backup commands, options and usage messages
@ -73,6 +73,9 @@ public final class BackupCommands {
public final static String INCORRECT_USAGE = "Incorrect usage"; public final static String INCORRECT_USAGE = "Incorrect usage";
public final static String TOP_LEVEL_NOT_ALLOWED =
"Top level (root) folder is not allowed to be a backup destination";
public static final String USAGE = "Usage: hbase backup COMMAND [command-specific arguments]\n" public static final String USAGE = "Usage: hbase backup COMMAND [command-specific arguments]\n"
+ "where COMMAND is one of:\n" + " create create a new backup image\n" + "where COMMAND is one of:\n" + " create create a new backup image\n"
+ " delete delete an existing backup image\n" + " delete delete an existing backup image\n"
@ -283,7 +286,11 @@ public final class BackupCommands {
printUsage(); printUsage();
throw new IOException(INCORRECT_USAGE); throw new IOException(INCORRECT_USAGE);
} }
String targetBackupDir = args[2];
// Check if backup destination is top level (root) folder - not allowed
if (isRootFolder(targetBackupDir)) {
throw new IOException(TOP_LEVEL_NOT_ALLOWED);
}
String tables = null; String tables = null;
// Check if we have both: backup set and list of tables // Check if we have both: backup set and list of tables
@ -331,7 +338,7 @@ public final class BackupCommands {
.withBackupType(BackupType.valueOf(args[1].toUpperCase())) .withBackupType(BackupType.valueOf(args[1].toUpperCase()))
.withTableList( .withTableList(
tables != null ? Lists.newArrayList(BackupUtils.parseTableNames(tables)) : null) tables != null ? Lists.newArrayList(BackupUtils.parseTableNames(tables)) : null)
.withTargetRootDir(args[2]).withTotalTasks(workers) .withTargetRootDir(targetBackupDir).withTotalTasks(workers)
.withBandwidthPerTasks(bandwidth).withBackupSetName(setName).build(); .withBandwidthPerTasks(bandwidth).withBackupSetName(setName).build();
String backupId = admin.backupTables(request); String backupId = admin.backupTables(request);
System.out.println("Backup session " + backupId + " finished. Status: SUCCESS"); System.out.println("Backup session " + backupId + " finished. Status: SUCCESS");
@ -341,6 +348,11 @@ public final class BackupCommands {
} }
} }
private boolean isRootFolder(String targetBackupDir) {
Path p = new Path(targetBackupDir);
return p.isRoot();
}
private boolean verifyPath(String path) { private boolean verifyPath(String path) {
try { try {
Path p = new Path(path); Path p = new Path(path);

View File

@ -98,8 +98,8 @@ public class TestBackupBase {
protected static final byte[] qualName = Bytes.toBytes("q1"); protected static final byte[] qualName = Bytes.toBytes("q1");
protected static final byte[] famName = Bytes.toBytes("f"); protected static final byte[] famName = Bytes.toBytes("f");
protected static String BACKUP_ROOT_DIR = "/backupUT"; protected static String BACKUP_ROOT_DIR = Path.SEPARATOR +"backupUT";
protected static String BACKUP_REMOTE_ROOT_DIR = "/backupUT"; protected static String BACKUP_REMOTE_ROOT_DIR = Path.SEPARATOR + "backupUT";
protected static String provider = "defaultProvider"; protected static String provider = "defaultProvider";
protected static boolean secure = false; protected static boolean secure = false;
@ -316,10 +316,14 @@ public class TestBackupBase {
conf1 = TEST_UTIL.getConfiguration(); conf1 = TEST_UTIL.getConfiguration();
TEST_UTIL.startMiniMapReduceCluster(); TEST_UTIL.startMiniMapReduceCluster();
BACKUP_ROOT_DIR = TEST_UTIL.getConfiguration().get("fs.defaultFS") + "/backupUT"; BACKUP_ROOT_DIR =
new Path ( new Path(TEST_UTIL.getConfiguration().get("fs.defaultFS")),
BACKUP_ROOT_DIR).toString();
LOG.info("ROOTDIR " + BACKUP_ROOT_DIR); LOG.info("ROOTDIR " + BACKUP_ROOT_DIR);
if (useSecondCluster) { if (useSecondCluster) {
BACKUP_REMOTE_ROOT_DIR = TEST_UTIL2.getConfiguration().get("fs.defaultFS") + "/backupUT"; BACKUP_REMOTE_ROOT_DIR =
new Path ( new Path(TEST_UTIL2.getConfiguration().get("fs.defaultFS"))
+ BACKUP_REMOTE_ROOT_DIR).toString();
LOG.info("REMOTE ROOTDIR " + BACKUP_REMOTE_ROOT_DIR); LOG.info("REMOTE ROOTDIR " + BACKUP_REMOTE_ROOT_DIR);
} }
createTables(); createTables();

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.hadoop.hbase.backup; package org.apache.hadoop.hbase.backup;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -80,6 +81,15 @@ public class TestBackupCommandLineTool {
assertTrue(output.indexOf(USAGE_DESCRIBE) >= 0); assertTrue(output.indexOf(USAGE_DESCRIBE) >= 0);
} }
@Test
public void testBackupDriverCreateTopLevelBackupDest() throws Exception {
String[] args = new String[] { "create", "full", "hdfs://localhost:1020", "-t", "t1" };
int result = ToolRunner.run(conf, new BackupDriver(), args);
// FAILED
assertEquals(1, result);
}
@Test @Test
public void testBackupDriverCreateHelp() throws Exception { public void testBackupDriverCreateHelp() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
@ -419,7 +429,7 @@ public class TestBackupCommandLineTool {
public void testBackupDriverBackupSetAndList() throws Exception { public void testBackupDriverBackupSetAndList() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.setOut(new PrintStream(baos)); System.setOut(new PrintStream(baos));
String[] args = new String[] { "create", "full", "file:/", "-t", "clicks", "-s", "s" }; String[] args = new String[] { "create", "full", "file:/localhost", "-t", "clicks", "-s", "s" };
ToolRunner.run(conf, new BackupDriver(), args); ToolRunner.run(conf, new BackupDriver(), args);
String output = baos.toString(); String output = baos.toString();