You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ha...@apache.org on 2009/02/19 22:51:19 UTC
svn commit: r746011 - in /hadoop/core/branches/branch-0.20: ./ CHANGES.txt
src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java
src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java
src/test/org/apache/hadoop/hdfs/TestReplication.java
Author: hairong
Date: Thu Feb 19 21:51:19 2009
New Revision: 746011
URL: http://svn.apache.org/viewvc?rev=746011&view=rev
Log:
Merge -r 746009:746010 from trunk to move the change of HADOOP-4692 to branch 0.20.
Modified:
hadoop/core/branches/branch-0.20/ (props changed)
hadoop/core/branches/branch-0.20/CHANGES.txt (contents, props changed)
hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java
hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java
hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestReplication.java
Propchange: hadoop/core/branches/branch-0.20/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Feb 19 21:51:19 2009
@@ -1,2 +1,2 @@
/hadoop/core/branches/branch-0.19:713112
-/hadoop/core/trunk:727001,727117,727191,727212,727217,727228,727255,727869,728187,729052,729987,732385,732572,732777,732838,732869,733887,734870,734916,736426,738328,738697,740077,740157,741703,741762,743745,743816,743892,744894,745180
+/hadoop/core/trunk:727001,727117,727191,727212,727217,727228,727255,727869,728187,729052,729987,732385,732572,732777,732838,732869,733887,734870,734916,736426,738328,738697,740077,740157,741703,741762,743745,743816,743892,744894,745180,746010
Modified: hadoop/core/branches/branch-0.20/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/CHANGES.txt?rev=746011&r1=746010&r2=746011&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/CHANGES.txt (original)
+++ hadoop/core/branches/branch-0.20/CHANGES.txt Thu Feb 19 21:51:19 2009
@@ -607,6 +607,9 @@
HADOOP-5254. The Configuration class should be able to work with XML
parsers that do not support xmlinclude. (Steve Loughran via dhruba)
+ HADOOP-4692. Namenode in infinite loop for replicating/deleting corrupt
+ blocks. (hairong)
+
Release 0.19.1 - Unreleased
IMPROVEMENTS
Propchange: hadoop/core/branches/branch-0.20/CHANGES.txt
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Feb 19 21:51:19 2009
@@ -1,3 +1,3 @@
/hadoop/core/branches/branch-0.18/CHANGES.txt:727226
/hadoop/core/branches/branch-0.19/CHANGES.txt:713112
-/hadoop/core/trunk/CHANGES.txt:727001,727117,727191,727212,727228,727255,727869,728187,729052,729987,732385,732572,732777,732838,732869,733887,734870,734916,735082,736426,738602,738697,739416,740077,740157,741703,741762,743296,743745,743816,743892,744894,745180,745268
+/hadoop/core/trunk/CHANGES.txt:727001,727117,727191,727212,727228,727255,727869,728187,729052,729987,732385,732572,732777,732838,732869,733887,734870,734916,735082,736426,738602,738697,739416,740077,740157,741703,741762,743296,743745,743816,743892,744894,745180,745268,746010
Modified: hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java?rev=746011&r1=746010&r2=746011&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java (original)
+++ hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/datanode/DataNode.java Thu Feb 19 21:51:19 2009
@@ -925,6 +925,7 @@
DatanodeInfo xferTargets[]
) throws IOException {
if (!data.isValidBlock(block)) {
+ // block does not exist or is under-construction
String errStr = "Can't send invalid block " + block;
LOG.info(errStr);
namenode.errorReport(dnRegistration,
@@ -933,6 +934,19 @@
return;
}
+ // Check if NN recorded length matches on-disk length
+ long onDiskLength = data.getLength(block);
+ if (block.getNumBytes() > onDiskLength) {
+ // Shorter on-disk len indicates corruption so report NN the corrupt block
+ namenode.reportBadBlocks(new LocatedBlock[]{
+ new LocatedBlock(block, new DatanodeInfo[] {
+ new DatanodeInfo(dnRegistration)})});
+ LOG.info("Can't replicate block " + block
+ + " because on-disk length " + onDiskLength
+ + " is shorter than NameNode recorded length " + block.getNumBytes());
+ return;
+ }
+
int numTargets = xferTargets.length;
if (numTargets > 0) {
if (LOG.isInfoEnabled()) {
@@ -1113,7 +1127,7 @@
out = new DataOutputStream(new BufferedOutputStream(baseStream,
SMALL_BUFFER_SIZE));
- blockSender = new BlockSender(b, 0, -1, false, false, false,
+ blockSender = new BlockSender(b, 0, b.getNumBytes(), false, false, false,
datanode);
DatanodeInfo srcNode = new DatanodeInfo(dnRegistration);
Modified: hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java?rev=746011&r1=746010&r2=746011&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java (original)
+++ hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java Thu Feb 19 21:51:19 2009
@@ -402,7 +402,7 @@
String block = DFSTestUtil.getFirstBlock(fs, fileName).getBlockName();
// Truncate replica of block
- truncateReplica(block, 0);
+ changeReplicaLength(block, 0, -1);
cluster.shutdown();
@@ -423,18 +423,22 @@
}
}
- private static void truncateReplica(String blockName, int dnIndex) throws IOException {
+ /**
+ * Change the length of a block at datanode dnIndex
+ */
+ static boolean changeReplicaLength(String blockName, int dnIndex, int lenDelta) throws IOException {
File baseDir = new File(System.getProperty("test.build.data"), "dfs/data");
for (int i=dnIndex*2; i<dnIndex*2+2; i++) {
File blockFile = new File(baseDir, "data" + (i+1)+ "/current/" +
blockName);
if (blockFile.exists()) {
RandomAccessFile raFile = new RandomAccessFile(blockFile, "rw");
- raFile.setLength(raFile.length()-1);
+ raFile.setLength(raFile.length()+lenDelta);
raFile.close();
- break;
+ return true;
}
}
+ return false;
}
private static void waitForBlockDeleted(String blockName, int dnIndex)
Modified: hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestReplication.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestReplication.java?rev=746011&r1=746010&r2=746011&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestReplication.java (original)
+++ hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestReplication.java Thu Feb 19 21:51:19 2009
@@ -388,7 +388,66 @@
if (cluster != null) {
cluster.shutdown();
}
+ }
+ }
+
+ /**
+ * Test if replication can detect mismatched length on-disk blocks
+ * @throws Exception
+ */
+ public void testReplicateLenMismatchedBlock() throws Exception {
+ MiniDFSCluster cluster = new MiniDFSCluster(new Configuration(), 2, true, null);
+ try {
+ cluster.waitActive();
+ // test truncated block
+ changeBlockLen(cluster, -1);
+ // test extended block
+ changeBlockLen(cluster, 1);
+ } finally {
+ cluster.shutdown();
}
- }
+ }
+ private void changeBlockLen(MiniDFSCluster cluster,
+ int lenDelta) throws IOException, InterruptedException {
+ final Path fileName = new Path("/file1");
+ final short REPLICATION_FACTOR = (short)1;
+ final FileSystem fs = cluster.getFileSystem();
+ final int fileLen = fs.getConf().getInt("io.bytes.per.checksum", 512);
+ DFSTestUtil.createFile(fs, fileName, fileLen, REPLICATION_FACTOR, 0);
+ DFSTestUtil.waitReplication(fs, fileName, REPLICATION_FACTOR);
+
+ String block = DFSTestUtil.getFirstBlock(fs, fileName).getBlockName();
+
+ // Change the length of a replica
+ for (int i=0; i<cluster.getDataNodes().size(); i++) {
+ if (TestDatanodeBlockScanner.changeReplicaLength(block, i, lenDelta)) {
+ break;
+ }
+ }
+
+ // increase the file's replication factor
+ fs.setReplication(fileName, (short)(REPLICATION_FACTOR+1));
+
+ // block replication triggers corrupt block detection
+ DFSClient dfsClient = new DFSClient(new InetSocketAddress("localhost",
+ cluster.getNameNodePort()), fs.getConf());
+ LocatedBlocks blocks = dfsClient.namenode.getBlockLocations(
+ fileName.toString(), 0, fileLen);
+ if (lenDelta < 0) { // replica truncated
+ while (!blocks.get(0).isCorrupt() ||
+ REPLICATION_FACTOR != blocks.get(0).getLocations().length) {
+ Thread.sleep(100);
+ blocks = dfsClient.namenode.getBlockLocations(
+ fileName.toString(), 0, fileLen);
+ }
+ } else { // no corruption detected; block replicated
+ while (REPLICATION_FACTOR+1 != blocks.get(0).getLocations().length) {
+ Thread.sleep(100);
+ blocks = dfsClient.namenode.getBlockLocations(
+ fileName.toString(), 0, fileLen);
+ }
+ }
+ fs.delete(fileName, true);
+ }
}