HDFS-3864. NN does not update internal file mtime for OP_CLOSE when reading from the edit log. Contributed by Aaron T. Myers.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1378413 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Aaron Myers 2012-08-29 01:19:07 +00:00
parent d4d2bf73a9
commit b2d186d865
3 changed files with 49 additions and 1 deletions

View File

@ -693,6 +693,9 @@ Branch-2 ( Unreleased changes )
HDFS-3849. When re-loading the FSImage, we should clear the existing HDFS-3849. When re-loading the FSImage, we should clear the existing
genStamp and leases. (Colin Patrick McCabe via atm) genStamp and leases. (Colin Patrick McCabe via atm)
HDFS-3864. NN does not update internal file mtime for OP_CLOSE when reading
from the edit log. (atm)
BREAKDOWN OF HDFS-3042 SUBTASKS BREAKDOWN OF HDFS-3042 SUBTASKS
HDFS-2185. HDFS portion of ZK-based FailoverController (todd) HDFS-2185. HDFS portion of ZK-based FailoverController (todd)

View File

@ -302,7 +302,9 @@ public class FSEditLogLoader {
addCloseOp.path); addCloseOp.path);
} }
// Update in-memory data structures // Update the salient file attributes.
oldFile.setAccessTime(addCloseOp.atime);
oldFile.setModificationTimeForce(addCloseOp.mtime);
updateBlocks(fsDir, addCloseOp, oldFile); updateBlocks(fsDir, addCloseOp, oldFile);
// Now close the file // Now close the file

View File

@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Random; import java.util.Random;
@ -32,12 +33,14 @@ import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo; import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.HdfsConstants.DatanodeReportType; import org.apache.hadoop.hdfs.protocol.HdfsConstants.DatanodeReportType;
import org.apache.hadoop.util.ThreadUtil;
import org.junit.Test; import org.junit.Test;
/** /**
* This class tests the decommissioning of nodes. * This class tests the decommissioning of nodes.
*/ */
public class TestModTime { public class TestModTime {
static final long seed = 0xDEADBEEFL; static final long seed = 0xDEADBEEFL;
static final int blockSize = 8192; static final int blockSize = 8192;
static final int fileSize = 16384; static final int fileSize = 16384;
@ -186,6 +189,46 @@ public class TestModTime {
cluster.shutdown(); cluster.shutdown();
} }
} }
/**
* Regression test for HDFS-3864 - NN does not update internal file mtime for
* OP_CLOSE when reading from the edit log.
*/
@Test
public void testModTimePersistsAfterRestart() throws IOException {
final long sleepTime = 10; // 10 milliseconds
MiniDFSCluster cluster = null;
FileSystem fs = null;
Configuration conf = new HdfsConfiguration();
try {
cluster = new MiniDFSCluster.Builder(conf).build();
fs = cluster.getFileSystem();
Path testPath = new Path("/test");
// Open a file, and get its initial modification time.
OutputStream out = fs.create(testPath);
long initialModTime = fs.getFileStatus(testPath).getModificationTime();
assertTrue(initialModTime > 0);
// Wait and then close the file. Ensure that the mod time goes up.
ThreadUtil.sleepAtLeastIgnoreInterrupts(sleepTime);
out.close();
long modTimeAfterClose = fs.getFileStatus(testPath).getModificationTime();
assertTrue(modTimeAfterClose >= initialModTime + sleepTime);
// Restart the NN, and make sure that the later mod time is still used.
cluster.restartNameNode();
long modTimeAfterRestart = fs.getFileStatus(testPath).getModificationTime();
assertEquals(modTimeAfterClose, modTimeAfterRestart);
} finally {
if (fs != null) {
fs.close();
}
if (cluster != null) {
cluster.shutdown();
}
}
}
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
new TestModTime().testModTime(); new TestModTime().testModTime();