[ 
https://issues.apache.org/jira/browse/HDFS-17722?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18062423#comment-18062423
 ] 

ASF GitHub Bot commented on HDFS-17722:
---------------------------------------

balodesecurity opened a new pull request, #8295:
URL: https://github.com/apache/hadoop/pull/8295

   ## Problem
   
   On a standby NameNode, a DataNode can get stuck in the 
`DECOMMISSION_INPROGRESS` state indefinitely when a timing race causes a 
replica to be flagged as **excess** instead of **live** during decommissioning.
   
   Sequence:
   1. File is written to DN-A, DN-B, DN-C (RF=3).
   2. DN-A is marked for decommission.
   3. The block manager schedules re-replication → copies a new replica to DN-D.
   4. On the standby NN, the block report for DN-D arrives *before* the 
decommission state for DN-A is propagated. The standby marks DN-D's replica as 
**excess** (it looks like an over-replicated block).
   5. The decommission monitor on the standby calls `isSufficient()`: 
`numLive=2` (DN-B, DN-C) satisfies RF=3? No. It sees only 2 live copies, so 
decommission stalls.
   6. Meanwhile DN-A is never fully decommissioned because `isSufficient()` 
never returns true.
   
   The excess replica on DN-D is a **physically present block copy** and 
contributes to durability — ignoring it causes the deadlock.
   
   ## Fix
   
   In `DatanodeAdminManager.isSufficient()`, count excess replicas alongside 
live replicas for the sufficiency check on non-under-construction blocks:
   
   ```java
   final int numLiveAndExcess = numLive + numberReplicas.excessReplicas();
   if (numLiveAndExcess >= blockManager.getDefaultStorageNum(block)
       && blockManager.hasMinStorage(block, numLive)) {
     return true;
   }
   ```
   
   The `hasMinStorage` guard (checks `dfs.replication.min`, default 1) ensures 
decommission does not proceed if zero live replicas exist — excess-only 
replicas are not guaranteed durable. After decommission completes, if the 
excess replica on DN-D is subsequently deleted, the block manager's normal 
under-replication detection will schedule re-replication.
   
   ## Testing
   
   **Unit tests** — `TestDatanodeAdminManagerIsSufficient` (5 tests, no cluster 
required):
   
   | Test | Scenario | Expected |
   |---|---|---|
   | `testExcessReplicaCountsTowardSufficiency` | HDFS-17722 bug: live=1, 
excess=1, RF=2 | `true` |
   | `testNormalDecommissionStillSufficient` | Baseline: live=2, excess=0, RF=2 
| `true` |
   | `testNoLiveReplicaBlocksDecommission` | Safety guard: live=0, excess=2, 
RF=2 | `false` |
   | `testInsufficientEvenWithExcess` | live=0, excess=1, RF=2 — not enough 
either way | `false` |
   | `testExcessAboveRFWithMinLive` | live=1, excess=2, RF=2 — excess 
over-covers RF | `true` |
   
   ```
   Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
   ```
   
   **Docker integration** — 3-DataNode cluster with 1 NameNode and RF=3, 5 
scenarios:
   - Scenario 1: Clean decommission (RF=2) — **PASS**
   - Scenario 2: RF=3→2 creates excess replicas, then decommission DN2 — 
**PASS**
   - Scenario 3: Same scenario on DN3 — **PASS**
   - Scenario 4: Repeated decommission + recommission cycles (3 rounds) — 
**PASS**
   - Scenario 5: Data integrity check after decommission — **PASS**
   
   ```
   Results: 0 failure(s) — ALL TESTS PASSED
   ```
   
   ## Related
   
   - JIRA: https://issues.apache.org/jira/browse/HDFS-17722




> DataNode stuck in decommissioning on standby NameNode
> -----------------------------------------------------
>
>                 Key: HDFS-17722
>                 URL: https://issues.apache.org/jira/browse/HDFS-17722
>             Project: Hadoop HDFS
>          Issue Type: Bug
>          Components: namenode
>    Affects Versions: 3.3.6
>            Reporter: Benoit Sigoure
>            Priority: Minor
>
> When decommissioning a DataNode in our cluster, we observed a situation where 
> the active NameNode had marked the DataNode as decommissioned but the standby 
> had it stuck in decommissioning state indefinitely (we waited 8h) due to a 
> block being allegedly under replicated (note: for this path the target 
> replication factor is 2x).  The standby NameNode kept logging this in a loop:
> {{2025-01-31 12:02:35,963 INFO BlockStateChange: Block: 
> blk_1486338012_426727507, Expected Replicas: 2, live replicas: 1, corrupt 
> replicas: 0, decommissioned replicas: 0, decommissioning replicas: 1, 
> maintenance replicas: 0, live entering maintenance replicas: 0, replicas on 
> stale nodes: 0, readonly replicas: 0, excess replicas: 1, Is Open File: 
> false, Datanodes having this block: 10.128.89.32:9866 10.128.118.216:9866 
> 10.128.49.6:9866 , Current Datanode: 10.128.118.216:9866, Is current datanode 
> decommissioning: true, Is current datanode entering maintenance: false}}
> Looking at the fsck report for this block, the active NameNode was reporting 
> the following:
> {code:java}
> Block Id: blk_1486338012
> Block belongs to: /path/to/file
> No. of Expected Replica: 2
> No. of live Replica: 2
> No. of excess Replica: 0
> No. of stale Replica: 0
> No. of decommissioned Replica: 1
> No. of decommissioning Replica: 0
> No. of corrupted Replica: 0
> Block replica on datanode/rack: datanode-v3-25-hadoop.hadoop/default-rack is 
> HEALTHY
> Block replica on datanode/rack: datanode-v3-39-hadoop.hadoop/default-rack is 
> DECOMMISSIONED
> Block replica on datanode/rack: datanode-v3-26-hadoop.hadoop/default-rack is 
> HEALTHY
> {code}
> Whereas on the standby it says:
> {code:java}
> Block Id: blk_1486338012
> Block belongs to: /path/to/file
> No. of Expected Replica: 2
> No. of live Replica: 1
> No. of excess Replica: 1
> No. of stale Replica: 0
> No. of decommissioned Replica: 0
> No. of decommissioning Replica: 1
> No. of corrupted Replica: 0
> Block replica on datanode/rack: datanode-v3-25-hadoop.hadoop/default-rack is 
> HEALTHY
> Block replica on datanode/rack: datanode-v3-39-hadoop.hadoop/default-rack is 
> DECOMMISSIONING
> Block replica on datanode/rack: datanode-v3-26-hadoop.hadoop/default-rack is 
> HEALTHY
> {code}
> {code:java}
> hadoop@namenode-0:/$ hdfs dfs -ls /path/to/file
> -rw-r--r-- 2 hbase supergroup 32453388896 2025-01-02 16:15 /path/to/file
> {code}
> After restarting the standby NameNode, the problem disappeared, the datanode 
> in question transitioned to decommissioned state as expected.
> Credits for the bug report go to Tomas Baltrunas at Arista.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to