smengcl opened a new pull request, #10788:
URL: https://github.com/apache/ozone/pull/10788

   ## What changes were proposed in this pull request?
   
   Unlike create/moveTableKeys/purge, `OMSnapshotDeleteRequest` never stamps 
`lastTransactionInfo`. `areSnapshotChangesFlushedToDB()` therefore reads the 
stale create-time stamp and reports an unflushed deletion as flushed, so 
`SnapshotDeletingService` does not defer it and can purge the snapshot while 
the delete and purge exist only in the double buffer. The purge empties the 
in-memory chain, `ReclaimableFilter` finds no previous snapshot 
(`areSnapshotChangesFlushedToDB(null)` is vacuously true), and 
`KeyDeletingService` hands blocks to SCM irreversibly while the on-disk 
`snapshotInfoTable` still shows the snapshot `ACTIVE` and referencing them.
   
   ```
   Ratis log                 applied (cache + chain)          RocksDB (flushed 
marker)
   idx 1: CreateSnapshot s1  s1 ACTIVE, lastTxnInfo = idx 1
   idx 2: DeleteKey k        tombstone k in AOS deletedTable  <flushed through 
idx 2>
   idx 3: DeleteSnapshot s1  s1 DELETED, lastTxnInfo NOT stamped (still idx 1)
      SDS gate: lastTxnInfo idx 1 <= flushed idx 2 => "flushed" (WRONG, delete 
is not durable);
      with the stamp: idx 3 > idx 2 => defer. Instead:
   idx 4-5: moveTableKeys + purge s1   in-memory chain now empty  (idx 3-5 
unflushed)
      KDS: no previous snapshot => k reclaimable => blocks deleted via SCM 
(irreversible)
      On-disk state: s1 ACTIVE, k captured in s1, k's blocks gone.
   ```
   
   ### Severity
   
   Low. The deletion was user-requested and Ratis-acked, DELETED snapshots 
cannot be unmarked, and crash recovery replays idx 3-5, so no supported flow 
reads the lost blocks. The inconsistency surfaces only via recovery that drops 
acked transactions (RocksDB restored without the matching Ratis log). Still 
worth fixing because both existing flush gates exist precisely to keep 
irreversible block deletion behind locally durable state, and the missing stamp 
silently defeats them. Found by model-checking the snapshot chain with 
[TLA+](https://en.wikipedia.org/wiki/TLA%2B), then reproduced in unit tests.
   
   ### Fix
   
   Stamp `lastTransactionInfo` in 
`OMSnapshotDeleteRequest.validateAndUpdateCache`, matching the other snapshot 
requests. The existing SDS gate then defers move/purge until the deletion is 
durable, so a chain-removed snapshot is at worst DELETED on disk, never ACTIVE.
   
   Cost: snapshot GC waits at most one double-buffer flush cycle.
   
   ## What is the link to the Apache JIRA
   
   https://issues.apache.org/jira/browse/HDDS-15888
   
   ## How was this patch tested?
   
   - New 
`TestOMSnapshotDeleteRequest#testSnapshotDeleteIsNotReportedFlushedUntilFlushed`:
 fails without the fix, passes with it.
   - New `TestReclaimableKeyFilter` boundary tests: empty-chain reclamation is 
only legal with the on-disk row absent or DELETED; javadoc records the 
invariant.
   - Tests are `Generated-by: Claude Code (Fable 5)`


-- 
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