|
@@ -28,6 +28,7 @@ import java.io.ByteArrayOutputStream;
|
|
|
import java.io.DataOutputStream;
|
|
|
import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
+import java.io.RandomAccessFile;
|
|
|
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.fs.FileUtil;
|
|
@@ -125,6 +126,48 @@ public class TestJournal {
|
|
|
Assert.assertEquals(1, segmentState.getStartTxId());
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test for HDFS-14557 to ensure that a edit file that failed to fully
|
|
|
+ * allocate and has a header byte of -1 is moved aside to allow startup
|
|
|
+ * to progress.
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ public void testEmptyEditsInProgressMovedAside() throws Exception {
|
|
|
+ // First, write 5 transactions to the journal
|
|
|
+ journal.startLogSegment(makeRI(1), 1,
|
|
|
+ NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION - 1);
|
|
|
+ final int numTxns = 5;
|
|
|
+ byte[] ops = QJMTestUtil.createTxnData(1, 5);
|
|
|
+ journal.journal(makeRI(2), 1, 1, numTxns, ops);
|
|
|
+ // Now close the segment
|
|
|
+ journal.finalizeLogSegment(makeRI(3), 1, numTxns);
|
|
|
+
|
|
|
+ // Create a new segment creating a new edits_inprogress file
|
|
|
+ journal.startLogSegment(makeRI(4), 6,
|
|
|
+ NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION - 1);
|
|
|
+ ops = QJMTestUtil.createTxnData(6, 5);
|
|
|
+ journal.journal(makeRI(5), 6, 6, numTxns, ops);
|
|
|
+ File eip = journal.getStorage().getInProgressEditLog(6);
|
|
|
+
|
|
|
+ // Now stop the journal without finalizing the segment
|
|
|
+ journal.close();
|
|
|
+
|
|
|
+ // Now "zero out" the EIP file with -1 bytes, similar to how it would
|
|
|
+ // appear if the pre-allocation failed
|
|
|
+ RandomAccessFile rwf = new RandomAccessFile(eip, "rw");
|
|
|
+ for (int i=0; i<rwf.length(); i++) {
|
|
|
+ rwf.write(-1);
|
|
|
+ }
|
|
|
+ rwf.close();
|
|
|
+
|
|
|
+ // Finally start the Journal again, and ensure the "zeroed out" file
|
|
|
+ // is renamed with a .empty extension
|
|
|
+ journal = new Journal(conf, TEST_LOG_DIR, JID, StartupOption.REGULAR,
|
|
|
+ mockErrorReporter);
|
|
|
+ File movedTo = new File(eip.getAbsolutePath()+".empty");
|
|
|
+ assertTrue(movedTo.exists());
|
|
|
+ }
|
|
|
+
|
|
|
@Test (timeout = 10000)
|
|
|
public void testEpochHandling() throws Exception {
|
|
|
assertEquals(0, journal.getLastPromisedEpoch());
|