From cbac1025662b6f42f34baf405c9b1e2108238f0f Mon Sep 17 00:00:00 2001 From: Wei-Chiu Chuang Date: Wed, 3 Apr 2019 11:00:12 -0700 Subject: [PATCH] HDFS-10477. Stop decommission a rack of DataNodes caused NameNode fail over to standby. Contributed by yunjiong zhao and Wei-Chiu Chuang. (cherry picked from commit be488b6070a124234c77f16193ee925d32ca9a20) (cherry picked from commit c8703dda0727e17d759d7ad27f0caee88103a530) (cherry picked from commit 2a94603ae66d9000c0bb07df0d592279339af103) --- .../server/blockmanagement/BlockManager.java | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java index 6337b50ef46..8be1734a362 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/BlockManager.java @@ -4119,21 +4119,41 @@ public class BlockManager implements BlockStatsMXBean { if (!isPopulatingReplQueues()) { return; } - final Iterator it = srcNode.getBlockIterator(); + int numExtraRedundancy = 0; - while(it.hasNext()) { - final BlockInfo block = it.next(); - if (block.isDeleted()) { - //Orphan block, will be handled eventually, skip + for (DatanodeStorageInfo datanodeStorageInfo : srcNode.getStorageInfos()) { + // the namesystem lock is released between iterations. Make sure the + // storage is not removed before continuing. + if (srcNode.getStorageInfo(datanodeStorageInfo.getStorageID()) == null) { continue; } - int expectedReplication = this.getExpectedRedundancyNum(block); - NumberReplicas num = countNodes(block); - if (shouldProcessExtraRedundancy(num, expectedReplication)) { - // extra redundancy block - processExtraRedundancyBlock(block, (short) expectedReplication, null, - null); - numExtraRedundancy++; + final Iterator it = datanodeStorageInfo.getBlockIterator(); + while(it.hasNext()) { + final BlockInfo block = it.next(); + if (block.isDeleted()) { + //Orphan block, will be handled eventually, skip + continue; + } + int expectedReplication = this.getExpectedRedundancyNum(block); + NumberReplicas num = countNodes(block); + if (shouldProcessExtraRedundancy(num, expectedReplication)) { + // extra redundancy block + processExtraRedundancyBlock(block, (short) expectedReplication, null, + null); + numExtraRedundancy++; + } + } + // When called by tests like TestDefaultBlockPlacementPolicy. + // testPlacementWithLocalRackNodesDecommissioned, it is not protected by + // lock, only when called by DatanodeManager.refreshNodes have writeLock + if (namesystem.hasWriteLock()) { + namesystem.writeUnlock(); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + namesystem.writeLock(); } } LOG.info("Invalidated {} extra redundancy blocks on {} after "