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 2008/12/19 02:18:17 UTC
svn commit: r727879 - in /hadoop/core/branches/branch-0.20: ./ CHANGES.txt
src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java
Author: hairong
Date: Thu Dec 18 17:18:16 2008
New Revision: 727879
URL: http://svn.apache.org/viewvc?rev=727879&view=rev
Log:
Merge -r 727211:727212 from trunk to move the change log of HADOOP-4810 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/namenode/FSNamesystem.java
hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestDatanodeBlockScanner.java
Propchange: hadoop/core/branches/branch-0.20/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Dec 18 17:18:16 2008
@@ -1,2 +1,2 @@
/hadoop/core/branches/branch-0.19:713112
-/hadoop/core/trunk:727001,727191,727217,727228,727255,727869
+/hadoop/core/trunk:727001,727191,727212,727217,727228,727255,727869
Modified: hadoop/core/branches/branch-0.20/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/CHANGES.txt?rev=727879&r1=727878&r2=727879&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/CHANGES.txt (original)
+++ hadoop/core/branches/branch-0.20/CHANGES.txt Thu Dec 18 17:18:16 2008
@@ -1552,6 +1552,8 @@
HADOOP-4857. Fixes TestUlimit to have exactly 1 map in the jobs spawned.
(Ravi Gummadi via ddas)
+ HADOOP-4810. Data lost at cluster startup time. (hairong)
+
HADOOP-4797. Improve how RPC server reads and writes large buffers. Avoids
soft-leak of direct buffers and excess copies in NIO layer. (Raghu Angadi)
Propchange: hadoop/core/branches/branch-0.20/CHANGES.txt
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Dec 18 17:18:16 2008
@@ -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,727191,727228,727255,727869
+/hadoop/core/trunk/CHANGES.txt:727001,727191,727212,727228,727255,727869
Modified: hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java?rev=727879&r1=727878&r2=727879&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java (original)
+++ hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java Thu Dec 18 17:18:16 2008
@@ -1518,13 +1518,13 @@
} else {
INodeFile inode = blocksMap.getINode(blk);
assert inode!=null : (blk + " in blocksMap must belongs to a file.");
+ // Add this replica to corruptReplicas Map
+ corruptReplicas.addToCorruptReplicasMap(blk, node);
if (countNodes(blk).liveReplicas()>inode.getReplication()) {
// the block is over-replicated so invalidate the replicas immediately
invalidateBlock(blk, node);
} else {
- // Add this replica to corruptReplicas Map and
// add the block to neededReplication
- corruptReplicas.addToCorruptReplicasMap(blk, node);
updateNeededReplications(blk, -1, 0);
}
}
@@ -1538,9 +1538,6 @@
NameNode.stateChangeLog.info("DIR* NameSystem.invalidateBlock: "
+ blk + " on "
+ dn.getName());
- if (isInSafeMode()) {
- throw new SafeModeException("Cannot invalidate block " + blk, safeMode);
- }
DatanodeDescriptor node = getDatanode(dn);
if (node == null) {
throw new IOException("Cannot invalidate block " + blk +
@@ -2776,7 +2773,7 @@
assert storedBlock != null : "Block must be stored by now";
if (block != storedBlock) {
- if (block.getNumBytes() > 0) {
+ if (block.getNumBytes() >= 0) {
long cursize = storedBlock.getNumBytes();
if (cursize == 0) {
storedBlock.setNumBytes(block.getNumBytes());
@@ -2788,12 +2785,13 @@
try {
if (cursize > block.getNumBytes()) {
// new replica is smaller in size than existing block.
- // Delete new replica.
- LOG.warn("Deleting block " + block + " from " + node.getName());
- invalidateBlock(block, node);
+ // Mark the new replica as corrupt.
+ LOG.warn("Mark new replica " + block + " from " + node.getName() +
+ "as corrupt because its length is shorter than existing ones");
+ markBlockAsCorrupt(block, node);
} else {
// new replica is larger in size than existing block.
- // Delete pre-existing replicas.
+ // Mark pre-existing replicas as corrupt.
int numNodes = blocksMap.numNodes(block);
int count = 0;
DatanodeDescriptor nodes[] = new DatanodeDescriptor[numNodes];
@@ -2805,9 +2803,9 @@
}
}
for (int j = 0; j < count; j++) {
- LOG.warn("Deleting block " + block + " from " +
- nodes[j].getName());
- invalidateBlock(block, nodes[j]);
+ LOG.warn("Mark existing replica " + block + " from " + node.getName() +
+ " as corrupt because its length is shorter than the new one");
+ markBlockAsCorrupt(block, nodes[j]);
}
//
// change the size of block in blocksMap
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=727879&r1=727878&r2=727879&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 Dec 18 17:18:16 2008
@@ -385,4 +385,67 @@
assertTrue(blocks.get(0).isCorrupt() == false);
cluster.shutdown();
}
+
+ /** Test if NameNode handles truncated blocks in block report */
+ public void testTruncatedBlockReport() throws Exception {
+ final Configuration conf = new Configuration();
+ final short REPLICATION_FACTOR = (short)2;
+
+ MiniDFSCluster cluster = new MiniDFSCluster(conf, REPLICATION_FACTOR, true, null);
+ cluster.waitActive();
+ FileSystem fs = cluster.getFileSystem();
+ try {
+ final Path fileName = new Path("/file1");
+ DFSTestUtil.createFile(fs, fileName, 1, REPLICATION_FACTOR, 0);
+ DFSTestUtil.waitReplication(fs, fileName, REPLICATION_FACTOR);
+
+ String block = DFSTestUtil.getFirstBlock(fs, fileName).getBlockName();
+
+ // Truncate replica of block
+ truncateReplica(block, 0);
+
+ cluster.shutdown();
+
+ // restart the cluster
+ cluster = new MiniDFSCluster(
+ 0, conf, REPLICATION_FACTOR, false, true, null, null, null);
+ cluster.startDataNodes(conf, 1, true, null, null);
+ cluster.waitActive(); // now we have 3 datanodes
+
+ // wait for truncated block be detected and the block to be replicated
+ DFSTestUtil.waitReplication(
+ cluster.getFileSystem(), fileName, REPLICATION_FACTOR);
+
+ // Make sure that truncated block will be deleted
+ waitForBlockDeleted(block, 0);
+ } finally {
+ cluster.shutdown();
+ }
+ }
+
+ private void truncateReplica(String blockName, int dnIndex) 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.close();
+ break;
+ }
+ }
+ }
+
+ private void waitForBlockDeleted(String blockName, int dnIndex)
+ throws IOException, InterruptedException {
+ File baseDir = new File(System.getProperty("test.build.data"), "dfs/data");
+ File blockFile1 = new File(baseDir, "data" + (2*dnIndex+1)+ "/current/" +
+ blockName);
+ File blockFile2 = new File(baseDir, "data" + (2*dnIndex+2)+ "/current/" +
+ blockName);
+ while (blockFile1.exists() || blockFile2.exists()) {
+ Thread.sleep(100);
+ }
+ }
}