Merged revision(s) 1613355 from hadoop/common/trunk:
HDFS-5919. FileJournalManager doesn't purge empty and corrupt inprogress edits files (vinayakumarb) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1613356 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9b98cd9c18
commit
100694c34e
|
@ -115,6 +115,9 @@ Release 2.6.0 - UNRELEASED
|
||||||
HDFS-6715. Webhdfs wont fail over when it gets java.io.IOException: Namenode
|
HDFS-6715. Webhdfs wont fail over when it gets java.io.IOException: Namenode
|
||||||
is in startup mode. (jing9)
|
is in startup mode. (jing9)
|
||||||
|
|
||||||
|
HDFS-5919. FileJournalManager doesn't purge empty and corrupt inprogress edits
|
||||||
|
files (vinayakumarb)
|
||||||
|
|
||||||
Release 2.5.0 - UNRELEASED
|
Release 2.5.0 - UNRELEASED
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -70,6 +70,8 @@ public class FileJournalManager implements JournalManager {
|
||||||
NameNodeFile.EDITS.getName() + "_(\\d+)-(\\d+)");
|
NameNodeFile.EDITS.getName() + "_(\\d+)-(\\d+)");
|
||||||
private static final Pattern EDITS_INPROGRESS_REGEX = Pattern.compile(
|
private static final Pattern EDITS_INPROGRESS_REGEX = Pattern.compile(
|
||||||
NameNodeFile.EDITS_INPROGRESS.getName() + "_(\\d+)");
|
NameNodeFile.EDITS_INPROGRESS.getName() + "_(\\d+)");
|
||||||
|
private static final Pattern EDITS_INPROGRESS_STALE_REGEX = Pattern.compile(
|
||||||
|
NameNodeFile.EDITS_INPROGRESS.getName() + "_(\\d+).*(\\S+)");
|
||||||
|
|
||||||
private File currentInProgress = null;
|
private File currentInProgress = null;
|
||||||
|
|
||||||
|
@ -161,8 +163,7 @@ public class FileJournalManager implements JournalManager {
|
||||||
throws IOException {
|
throws IOException {
|
||||||
LOG.info("Purging logs older than " + minTxIdToKeep);
|
LOG.info("Purging logs older than " + minTxIdToKeep);
|
||||||
File[] files = FileUtil.listFiles(sd.getCurrentDir());
|
File[] files = FileUtil.listFiles(sd.getCurrentDir());
|
||||||
List<EditLogFile> editLogs =
|
List<EditLogFile> editLogs = matchEditLogs(files, true);
|
||||||
FileJournalManager.matchEditLogs(files);
|
|
||||||
for (EditLogFile log : editLogs) {
|
for (EditLogFile log : editLogs) {
|
||||||
if (log.getFirstTxId() < minTxIdToKeep &&
|
if (log.getFirstTxId() < minTxIdToKeep &&
|
||||||
log.getLastTxId() < minTxIdToKeep) {
|
log.getLastTxId() < minTxIdToKeep) {
|
||||||
|
@ -245,6 +246,11 @@ public class FileJournalManager implements JournalManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<EditLogFile> matchEditLogs(File[] filesInStorage) {
|
static List<EditLogFile> matchEditLogs(File[] filesInStorage) {
|
||||||
|
return matchEditLogs(filesInStorage, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<EditLogFile> matchEditLogs(File[] filesInStorage,
|
||||||
|
boolean forPurging) {
|
||||||
List<EditLogFile> ret = Lists.newArrayList();
|
List<EditLogFile> ret = Lists.newArrayList();
|
||||||
for (File f : filesInStorage) {
|
for (File f : filesInStorage) {
|
||||||
String name = f.getName();
|
String name = f.getName();
|
||||||
|
@ -255,6 +261,7 @@ public class FileJournalManager implements JournalManager {
|
||||||
long startTxId = Long.parseLong(editsMatch.group(1));
|
long startTxId = Long.parseLong(editsMatch.group(1));
|
||||||
long endTxId = Long.parseLong(editsMatch.group(2));
|
long endTxId = Long.parseLong(editsMatch.group(2));
|
||||||
ret.add(new EditLogFile(f, startTxId, endTxId));
|
ret.add(new EditLogFile(f, startTxId, endTxId));
|
||||||
|
continue;
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
LOG.error("Edits file " + f + " has improperly formatted " +
|
LOG.error("Edits file " + f + " has improperly formatted " +
|
||||||
"transaction ID");
|
"transaction ID");
|
||||||
|
@ -269,12 +276,30 @@ public class FileJournalManager implements JournalManager {
|
||||||
long startTxId = Long.parseLong(inProgressEditsMatch.group(1));
|
long startTxId = Long.parseLong(inProgressEditsMatch.group(1));
|
||||||
ret.add(
|
ret.add(
|
||||||
new EditLogFile(f, startTxId, HdfsConstants.INVALID_TXID, true));
|
new EditLogFile(f, startTxId, HdfsConstants.INVALID_TXID, true));
|
||||||
|
continue;
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
LOG.error("In-progress edits file " + f + " has improperly " +
|
LOG.error("In-progress edits file " + f + " has improperly " +
|
||||||
"formatted transaction ID");
|
"formatted transaction ID");
|
||||||
// skip
|
// skip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (forPurging) {
|
||||||
|
// Check for in-progress stale edits
|
||||||
|
Matcher staleInprogressEditsMatch = EDITS_INPROGRESS_STALE_REGEX
|
||||||
|
.matcher(name);
|
||||||
|
if (staleInprogressEditsMatch.matches()) {
|
||||||
|
try {
|
||||||
|
long startTxId = Long.valueOf(staleInprogressEditsMatch.group(1));
|
||||||
|
ret.add(new EditLogFile(f, startTxId, HdfsConstants.INVALID_TXID,
|
||||||
|
true));
|
||||||
|
continue;
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
LOG.error("In-progress stale edits file " + f + " has improperly "
|
||||||
|
+ "formatted transaction ID");
|
||||||
|
// skip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,18 +212,25 @@ public class TestNNStorageRetentionManager {
|
||||||
tc.addImage("/foo1/current/" + getImageFileName(300), false);
|
tc.addImage("/foo1/current/" + getImageFileName(300), false);
|
||||||
tc.addImage("/foo1/current/" + getImageFileName(400), false);
|
tc.addImage("/foo1/current/" + getImageFileName(400), false);
|
||||||
|
|
||||||
|
// Segments containing txns upto txId 250 are extra and should be purged.
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(1, 100), true);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(1, 100), true);
|
||||||
// Without lowering the max segments to retain, we'd retain all segments
|
|
||||||
// going back to txid 150 (300 - 150).
|
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(101, 175), true);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(101, 175), true);
|
||||||
|
tc.addLog("/foo2/current/" + getInProgressEditsFileName(176) + ".empty",
|
||||||
|
true);
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(176, 200), true);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(176, 200), true);
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(201, 225), true);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(201, 225), true);
|
||||||
|
tc.addLog("/foo2/current/" + getInProgressEditsFileName(226) + ".corrupt",
|
||||||
|
true);
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(226, 240), true);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(226, 240), true);
|
||||||
// Only retain 2 extra segments. The 301-350 and 351-400 segments are
|
// Only retain 2 extra segments. The 301-350 and 351-400 segments are
|
||||||
// considered required, not extra.
|
// considered required, not extra.
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(241, 275), false);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(241, 275), false);
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(276, 300), false);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(276, 300), false);
|
||||||
|
tc.addLog("/foo2/current/" + getInProgressEditsFileName(301) + ".empty",
|
||||||
|
false);
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(301, 350), false);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(301, 350), false);
|
||||||
|
tc.addLog("/foo2/current/" + getInProgressEditsFileName(351) + ".corrupt",
|
||||||
|
false);
|
||||||
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(351, 400), false);
|
tc.addLog("/foo2/current/" + getFinalizedEditsFileName(351, 400), false);
|
||||||
tc.addLog("/foo2/current/" + getInProgressEditsFileName(401), false);
|
tc.addLog("/foo2/current/" + getInProgressEditsFileName(401), false);
|
||||||
runTest(tc);
|
runTest(tc);
|
||||||
|
|
Loading…
Reference in New Issue