Index: hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java (revision 1592884) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestExportSnapshot.java (working copy) @@ -175,6 +175,12 @@ public void testExportFileSystemState() throws Exception { testExportFileSystemState(tableName, snapshotName, 2); } + + @Test + public void testExportFileSystemStateWithSkipTmp() throws Exception { + TEST_UTIL.getConfiguration().setBoolean(ExportSnapshot.CONF_SKIP_TMP, true); + testExportFileSystemState(tableName, snapshotName, 2); + } @Test public void testEmptyExportFileSystemState() throws Exception { Index: hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java (revision 1592884) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/ExportSnapshot.java (working copy) @@ -90,6 +90,7 @@ private static final String CONF_BUFFER_SIZE = "snapshot.export.buffer.size"; private static final String CONF_MAP_GROUP = "snapshot.export.default.map.group"; private static final String CONF_BANDWIDTH_MB = "snapshot.export.map.bandwidth.mb"; + protected static final String CONF_SKIP_TMP = "snapshot.export.skip.tmp"; static final String CONF_TEST_FAILURE = "test.snapshot.export.failure"; static final String CONF_TEST_RETRY = "test.snapshot.export.failure.retry"; @@ -725,11 +726,14 @@ LOG.debug("inputFs=" + inputFs.getUri().toString() + " inputRoot=" + inputRoot); FileSystem outputFs = FileSystem.get(outputRoot.toUri(), conf); LOG.debug("outputFs=" + outputFs.getUri().toString() + " outputRoot=" + outputRoot.toString()); + + boolean skipTmp = conf.getBoolean(CONF_SKIP_TMP, false); Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, inputRoot); Path snapshotTmpDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(snapshotName, outputRoot); Path outputSnapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, outputRoot); - + Path initialOutputSnapshotDir = skipTmp? outputSnapshotDir: snapshotTmpDir; + // Check if the snapshot already exists if (outputFs.exists(outputSnapshotDir)) { if (overwrite) { @@ -744,18 +748,20 @@ } } - // Check if the snapshot already in-progress - if (outputFs.exists(snapshotTmpDir)) { - if (overwrite) { - if (!outputFs.delete(snapshotTmpDir, true)) { - System.err.println("Unable to remove existing snapshot tmp directory: " + snapshotTmpDir); + if (!skipTmp) { + // Check if the snapshot already in-progress + if (outputFs.exists(snapshotTmpDir)) { + if (overwrite) { + if (!outputFs.delete(snapshotTmpDir, true)) { + System.err.println("Unable to remove existing snapshot tmp directory: " + snapshotTmpDir); + return 1; + } + } else { + System.err.println("A snapshot with the same name '"+ snapshotName +"' may be in-progress"); + System.err.println("Please check " + snapshotTmpDir + ". If the snapshot has completed, "); + System.err.println("consider removing "+ snapshotTmpDir +" by using the -overwrite option"); return 1; } - } else { - System.err.println("A snapshot with the same name '"+ snapshotName +"' may be in-progress"); - System.err.println("Please check " + snapshotTmpDir + ". If the snapshot has completed, "); - System.err.println("consider removing "+ snapshotTmpDir +" by using the -overwrite option"); - return 1; } } @@ -772,10 +778,10 @@ // will remove them because they are unreferenced. try { LOG.info("Copy Snapshot Manifest"); - FileUtil.copy(inputFs, snapshotDir, outputFs, snapshotTmpDir, false, false, conf); + FileUtil.copy(inputFs, snapshotDir, outputFs, initialOutputSnapshotDir, false, false, conf); } catch (IOException e) { throw new ExportSnapshotException("Failed to copy the snapshot directory: from=" + - snapshotDir + " to=" + snapshotTmpDir, e); + snapshotDir + " to=" + initialOutputSnapshotDir, e); } // Step 2 - Start MR Job to copy files @@ -789,12 +795,15 @@ filesUser, filesGroup, filesMode, mappers, bandwidthMB); } - // Step 3 - Rename fs2:/.snapshot/.tmp/ fs2:/.snapshot/ + LOG.info("Finalize the Snapshot Export"); - if (!outputFs.rename(snapshotTmpDir, outputSnapshotDir)) { - throw new ExportSnapshotException("Unable to rename snapshot directory from=" + - snapshotTmpDir + " to=" + outputSnapshotDir); - } + if (!skipTmp) { + // Step 3 - Rename fs2:/.snapshot/.tmp/ fs2:/.snapshot/ + if (!outputFs.rename(snapshotTmpDir, outputSnapshotDir)) { + throw new ExportSnapshotException("Unable to rename snapshot directory from=" + + snapshotTmpDir + " to=" + outputSnapshotDir); + } + } // Step 4 - Verify snapshot validity LOG.info("Verify snapshot validity"); @@ -804,7 +813,9 @@ return 0; } catch (Exception e) { LOG.error("Snapshot export failed", e); - outputFs.delete(snapshotTmpDir, true); + if (!skipTmp) { + outputFs.delete(snapshotTmpDir, true); + } outputFs.delete(outputSnapshotDir, true); return 1; }