wang-haihua opened a new pull request, #3837:
URL: https://github.com/apache/celeborn/pull/3837

   ### What changes were proposed in this pull request?
   
   Add a `committed` flag on `TierWriterBase`, set in `close()` right before 
`notifyFileCommitted()` (exactly when the file becomes durable and fetchable). 
`PartitionDataWriter.notifyError` then skips `destroy()` when the writer is 
already committed, so a disk `CRITICAL_ERROR` broadcast no longer deletes 
committed files.
   
   The rollback path (`Controller.destroyWriters`) and shuffle-expiry cleanup 
(`StorageManager.cleanFileInternal`) call `destroy()` directly rather than 
through `notifyError`, so they are unaffected and still remove committed files 
when the shuffle actually ends.
   
   ### Why are the changes needed?
   
   `DeviceMonitor` broadcasts `CRITICAL_ERROR` to every writer registered on a 
disk:
   
   ```
   ObservedDevice.notifyObserversOnError(CRITICAL_ERROR)
     -> PartitionDataWriter.notifyError -> destroy(IOException)
     -> TierWriterBase.destroy -> cleanLocalOrDfsFiles()
     -> DiskFileInfo.deleteAllFiles(null)   // deletes data + index + sorted 
files
   ```
   
   A `LocalTierWriter` registers as an observer at file creation and, before 
this fix, is removed from the observer set only on the `destroy` path — never 
when the file commits. So a committed writer stays registered for the entire 
remaining lifetime of the shuffle. If the disk crosses the `CRITICAL_ERROR` 
threshold during that window, the broadcast destroys the committed writer and 
deletes its data/index/sorted files out from under in-flight reducers, causing 
`FileNotFoundException` on fetch and genuine shuffle data loss. The broadcast 
hits every observer on the disk, so a committed file is deleted merely for 
sharing a disk with unrelated failing writes.
   
   See [CELEBORN-2452](https://issues.apache.org/jira/browse/CELEBORN-2452) for 
full analysis.
   
   ### Does this PR resolve a correctness bug?
   
   - [x] Yes
   
   ### Does this PR introduce _any_ user-facing change?
   
   No.
   
   ### How was this patch tested?
   
   - Traced every `destroy()` caller to confirm the guard belongs at the 
`notifyError` entry (device-error broadcast) and not inside `destroy()`, which 
is shared with the rollback/expiry paths that must still delete committed files.
   - Verified `worker` (with dependent modules) `test-compile` passes, 
confirming the Scala `@volatile var committed` getter is callable from the Java 
`PartitionDataWriter`.


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