kerneltime commented on code in PR #10496:
URL: https://github.com/apache/ozone/pull/10496#discussion_r3717792819


##########
hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueHandler.java:
##########
@@ -1962,7 +1975,18 @@ private long reconcileChunksPerBlock(KeyValueContainer 
container, Pipeline pipel
       if (!localOffset2Chunk.isEmpty()) {
         List<ContainerProtos.ChunkInfo> allChunks = new 
ArrayList<>(localOffset2Chunk.values());
         localBlockData.setChunks(allChunks);
-        putBlockForClosedContainer(container, localBlockData, maxBcsId, 
allChunksSuccessful);
+        // The peer's BCSID attests exactly the chunk list in its committed 
BlockData, so that list is the oracle for
+        // adopting it -- not the diff-derived peerChunkList, which omits 
chunks the peer's scanner marked unhealthy
+        // (and the in-loop unhealthy skip above does not clear 
allChunksSuccessful). Without this check a trailing
+        // unrepairable peer chunk lets the BCSID advance past data we do not 
hold: the replica would then admit
+        // reads it cannot serve and look complete to SCM's sequenceId-based 
source and delete selection.
+        boolean adoptPeerBcsId = allChunksSuccessful && 
coversPeerBlock(peerBlockData, localOffset2Chunk);
+        if (allChunksSuccessful && !adoptPeerBcsId) {
+          LOG.warn("Repaired all {} diff chunks for block {} in container {} 
from peer {}, but the local block does " +
+              "not cover the peer's committed chunk list. BCSID stays at the 
local value.",
+              peerChunkList.size(), localID, containerID, peer);
+        }
+        putBlockForClosedContainer(container, localBlockData, maxBcsId, 
adoptPeerBcsId);

Review Comment:
   Confirmed with your repro exactly as written (red with `expected: <1> but 
was: <99>`), and fixed in fcd21185c4 by the separation you suggested: per-block 
repair never touches the container BCSID; `reconcileContainerInternal` 
accumulates coverage across the round and advances the container in one 
round-end step only when no repaired block stayed partial. A clean round 
converges exactly as before, so recovery availability is unchanged.
   
   Your finding prompted a sweep for remaining lanes of this class, which found 
one more (df197124fc): a block whose *only* differences are peer-unhealthy 
chunks vanishes from the diff entirely -- `reportChunkIfHealthy` drops its 
entries, so it can never dirty the round through a partial repair. That is 
literally round two of your own scenario, after round one has correctly 
recovered everything recoverable. `ContainerDiffReport` now counts filter drops 
and the round-end advancement also requires zero drops. The one remaining lane 
-- data absent from both replicas' trees -- is invisible to any diff by 
construction; advancing there inherits the peer's own container claim at the 
same trust level as wholesale replication, and is documented as the accepted 
boundary in the helper javadoc.
   
   On the tree-match variant you floated: it needs the peer's *container* 
BCSID, which `getContainerChecksumInfo` deliberately does not carry (the #7474 
review deferred exactly that -- it would take a readContainer call or a proto 
change). Round-coverage needs no new RPC and is strictly conservative. The 
fuller tree-equality adoption stays scoped in HDDS-16011.
   
   Tests: your two-block regression essentially verbatim plus a round-end 
suppression assertion, the filtered-only-block regression driving the real 
`diff()`, and the positive control extended across the round-end seam. All fail 
without their respective guards; full run 181/181 across the reconcile, diff, 
checksum-manager, and mock-datanode suites.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to