Stephen0421 commented on PR #9207:
URL: https://github.com/apache/paimon/pull/9207#issuecomment-5305745425

   > * After `deleteQuietly` fails, the count of deleted files and bytes is 
still accumulated and the path is returned, causing Local, Flink, and Spark to 
falsely report success.
   > * There is no lease commit between the two reachability scans and the 
actual deletion; concurrent compaction might commit a snapshot that 
re-references an old pack, which is subsequently deleted by GC, creating a 
window for data loss.
   
   Thanks for the review.
   
   ### 1. False success after `deleteQuietly` fails
   
   Fixed.
   
   Pack deletion now uses `FileIO.delete()`, and a file is counted as deleted 
only when the deletion actually succeeds. The Local, Flink, and Spark 
implementations all use this path.
   
   This is covered by `testDeleteFailureIsNotReported`.
   
   ### 2. No lease between the two scans and deletion
   
   This is a fair concern. We investigated whether a concurrent compaction 
could commit after the final reachability scan and re-reference a pack already 
included in the deletion set.
   
   In the current managed-blob compaction path, reused pack references are 
written to the output data file's `.blobref` based on the compaction inputs 
(`compactBefore`). Therefore, at the final scan, a pack `P` falls into one of 
two cases:
   
   1. **The compaction inputs are still live.**
   
      A retained `ADD` data file already contains a `.blobref` referencing `P`, 
so the final scan marks `P` as used. A later successful compaction may reuse 
`P`, but `P` is not in the deletion set.
   
   2. **The final scan marks `P` as unused.**
   
      No retained or current data file references `P`. A prepared compaction 
that still holds a descriptor for `P` must have been created from inputs that 
have since expired. Committing that compaction requires deleting its 
`compactBefore` files, and conflict detection rejects the commit with `File 
deletion conflicts detected`.
   
   Equivalently, if a `compactBefore` file is still present and references `P`, 
the final reachability scan treats `P` as live, so it cannot become a GC 
candidate.
   
   We added deterministic tests for both cases:
   
   - `testSuccessfulCompactionAfterFinalMarkKeepsReusedPacks`: a compaction 
based on live inputs successfully commits after the used set is frozen. Its 
reused packs remain protected, while a genuine orphan is deleted.
   - `testStaleCompactionCannotCommitAfterFinalMark`: a compaction based on 
expired inputs attempts to commit at deletion time. The commit is rejected, and 
the packs it attempted to reuse are safely deleted.
   
   Based on the current compaction invariants, we do not believe a lease is 
required for this initial version.
   
   `older_than` is still required, but it is not a commit fence; it protects 
files that were written recently. Compaction reuse does not refresh a pack's 
modification time, but the two cases above ensure that a live reused pack 
remains reachable and is not deleted.
   
   If there is a compaction or rewrite path that can reference a pack outside 
its `compactBefore` inputs, that would be a real gap and should be handled 
separately.


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

Reply via email to