HDFS-7373. Clean up temporary files after fsimage transfer failures. Contributed by Kihwal Lee

(cherry picked from commit c0d666c74e)
This commit is contained in:
Kihwal Lee 2014-12-18 13:00:18 -06:00
parent 8854c78015
commit 8bffaa46fc
3 changed files with 43 additions and 0 deletions

View File

@ -211,6 +211,9 @@ Release 2.7.0 - UNRELEASED
HDFS-7531. Improve the concurrent access on FsVolumeList (Lei Xu via Colin HDFS-7531. Improve the concurrent access on FsVolumeList (Lei Xu via Colin
P. McCabe) P. McCabe)
HDFS-7373. Clean up temporary files after fsimage transfer failures.
(kihwal)
OPTIMIZATIONS OPTIMIZATIONS
HDFS-7454. Reduce memory footprint for AclEntries in NameNode. HDFS-7454. Reduce memory footprint for AclEntries in NameNode.

View File

@ -528,10 +528,18 @@ public class TransferFsImage {
fos.getChannel().force(true); fos.getChannel().force(true);
fos.close(); fos.close();
} }
// Something went wrong and did not finish reading.
// Remove the temporary files.
if (!finishedReceiving) {
deleteTmpFiles(localPaths);
}
if (finishedReceiving && received != advertisedSize) { if (finishedReceiving && received != advertisedSize) {
// only throw this exception if we think we read all of it on our end // only throw this exception if we think we read all of it on our end
// -- otherwise a client-side IOException would be masked by this // -- otherwise a client-side IOException would be masked by this
// exception that makes it look like a server-side problem! // exception that makes it look like a server-side problem!
deleteTmpFiles(localPaths);
throw new IOException("File " + url + " received length " + received + throw new IOException("File " + url + " received length " + received +
" is not of the advertised size " + " is not of the advertised size " +
advertisedSize); advertisedSize);
@ -548,6 +556,7 @@ public class TransferFsImage {
if (advertisedDigest != null && if (advertisedDigest != null &&
!computedDigest.equals(advertisedDigest)) { !computedDigest.equals(advertisedDigest)) {
deleteTmpFiles(localPaths);
throw new IOException("File " + url + " computed digest " + throw new IOException("File " + url + " computed digest " +
computedDigest + " does not match advertised digest " + computedDigest + " does not match advertised digest " +
advertisedDigest); advertisedDigest);
@ -558,6 +567,18 @@ public class TransferFsImage {
} }
} }
private static void deleteTmpFiles(List<File> files) {
if (files == null) {
return;
}
LOG.info("Deleting temporary files: " + files);
for (File file : files) {
file.delete(); // ignore the return value
}
}
private static MD5Hash parseMD5Header(HttpURLConnection connection) { private static MD5Hash parseMD5Header(HttpURLConnection connection) {
String header = connection.getHeaderField(MD5_HEADER); String header = connection.getHeaderField(MD5_HEADER);
return (header != null) ? new MD5Hash(header) : null; return (header != null) ? new MD5Hash(header) : null;

View File

@ -643,6 +643,22 @@ public class TestCheckpoint {
}); });
} }
private void checkTempImages(NNStorage storage) throws IOException {
List<File> dirs = new ArrayList<File>();
dirs.add(storage.getStorageDir(0).getCurrentDir());
dirs.add(storage.getStorageDir(1).getCurrentDir());
for (File dir : dirs) {
File[] list = dir.listFiles();
for (File f : list) {
// Throw an exception if a temp image file is found.
if(f.getName().contains(NNStorage.NameNodeFile.IMAGE_NEW.getName())) {
throw new IOException("Found " + f);
}
}
}
}
/** /**
* Simulate 2NN failing to send the whole file (error type 3) * Simulate 2NN failing to send the whole file (error type 3)
* The length header in the HTTP transfer should prevent * The length header in the HTTP transfer should prevent
@ -704,6 +720,9 @@ public class TestCheckpoint {
GenericTestUtils.assertExceptionContains(exceptionSubstring, e); GenericTestUtils.assertExceptionContains(exceptionSubstring, e);
} }
Mockito.reset(faultInjector); Mockito.reset(faultInjector);
// Make sure there is no temporary files left around.
checkTempImages(cluster.getNameNode().getFSImage().getStorage());
checkTempImages(secondary.getFSImage().getStorage());
secondary.shutdown(); // secondary namenode crash! secondary.shutdown(); // secondary namenode crash!
secondary = null; secondary = null;