HDFS-5475. NN incorrectly tracks more than one replica per DN.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-2832@1539890 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Arpit Agarwal 2013-11-08 01:01:18 +00:00
parent 2af29af098
commit 06d24efed0
3 changed files with 32 additions and 5 deletions

View File

@ -84,3 +84,7 @@ IMPROVEMENTS:
HDFS-5472. Fix TestDatanodeManager, TestSafeMode and HDFS-5472. Fix TestDatanodeManager, TestSafeMode and
TestNNThroughputBenchmark (Contributed by szetszwo) TestNNThroughputBenchmark (Contributed by szetszwo)
HDFS-5475. NN incorrectly tracks more than one replica per DN. (Arpit
Agarwal)

View File

@ -195,14 +195,24 @@ public class BlockInfo extends Block implements LightWeightGSet.LinkedElement {
* Add a {@link DatanodeStorageInfo} location for a block * Add a {@link DatanodeStorageInfo} location for a block
*/ */
boolean addStorage(DatanodeStorageInfo storage) { boolean addStorage(DatanodeStorageInfo storage) {
if(findStorageInfo(storage) >= 0) // the node is already there boolean added = true;
return false; int idx = findDatanode(storage.getDatanodeDescriptor());
if(idx >= 0) {
if (getStorageInfo(idx) == storage) { // the storage is already there
return false;
} else {
// The block is on the DN but belongs to a different storage.
// Update our state.
removeStorage(storage);
added = false; // Just updating storage. Return false.
}
}
// find the last null node // find the last null node
int lastNode = ensureCapacity(1); int lastNode = ensureCapacity(1);
setStorageInfo(lastNode, storage); setStorageInfo(lastNode, storage);
setNext(lastNode, null); setNext(lastNode, null);
setPrevious(lastNode, null); setPrevious(lastNode, null);
return true; return added;
} }
/** /**

View File

@ -297,9 +297,22 @@ public class BlockInfoUnderConstruction extends BlockInfo {
void addReplicaIfNotPresent(DatanodeStorageInfo storage, void addReplicaIfNotPresent(DatanodeStorageInfo storage,
Block block, Block block,
ReplicaState rState) { ReplicaState rState) {
for(ReplicaUnderConstruction r : replicas) Iterator<ReplicaUnderConstruction> it = replicas.iterator();
if(r.getExpectedStorageLocation() == storage) while (it.hasNext()) {
ReplicaUnderConstruction r = it.next();
if(r.getExpectedStorageLocation() == storage) {
return; return;
} else if (r.getExpectedStorageLocation().getDatanodeDescriptor() ==
storage.getDatanodeDescriptor()) {
// The Datanode reported that the block is on a different storage
// than the one chosen by BlockPlacementPolicy. This can occur as
// we allow Datanodes to choose the target storage. Update our
// state by removing the stale entry and adding a new one.
it.remove();
break;
}
}
replicas.add(new ReplicaUnderConstruction(block, storage, rState)); replicas.add(new ReplicaUnderConstruction(block, storage, rState));
} }