wombatu-kun opened a new pull request, #8698:
URL: https://github.com/apache/paimon/pull/8698

   ### Purpose
   
   Streaming reads of postpone bucket tables with `streaming-read-overwrite` 
enabled silently lose data.
   
   `ContinuousFileSplitEnumerator#assignSuggestedTask(IncrementalSplit)` 
returns `split.bucket()` as is, which is `BucketMode.POSTPONE_BUCKET` (-2) for 
postpone bucket tables. `ChannelComputer#select` then computes `-2 % 
parallelism == -2`, and `PreAssignSplitAssigner` stores the split under map key 
-2 while `getNext(subtask)` is only ever called with a subtask in `[0, 
parallelism)`. The split is therefore never handed to any reader. Because 
`remainingSplits()` still includes it, the split is checkpointed and stays 
stranded across restore. Neither an exception nor a log is produced.
   
   The sibling overload `assignSuggestedTask(DataSplit)` already handles 
postpone buckets. That handling was added in #6142 ("Fix postpone bucket 
without changelog producer cannot read all records with multiple streaming 
readers"). The incremental plan path used to be covered by it, but #7093 moved 
incremental plans from `DataSplit` to `IncrementalSplit` and the new overload 
was left with a `// TODO how to deal with postpone bucket?` instead, which 
reintroduced the same bug.
   
   The reachable configuration is the default one. `DataTableStreamScan` only 
applies `onlyReadRealBuckets()` when `changelog-producer != none`, and 
`SchemaValidation` rejects `streaming-read-overwrite` together with 
`full-compaction` / `lookup`, so `none` (the default, and the affected one) and 
`input` (unaffected) are the only options left.
   
   This PR mirrors the postpone branch of the `DataSplit` overload. 
`IncrementalSplit` has no `dataFiles()`, and a diff which only removes files 
has no after files, so the write id is read from the after files with a 
fallback to the before files. It reuses the existing 
`PostponeBucketFileStoreWrite#getWriteId`.
   
   Since the failure mode is silent, which is precisely why the bug survived 
being fixed once already, `assignSuggestedTask` now also validates that the 
suggested task lies within `[0, parallelism)` and fails loudly otherwise. 
`UNAWARE_BUCKET` is 0 and `POSTPONE_BUCKET` is the only negative bucket value, 
so this does not affect existing paths.
   
   ### Tests
   
   Added three cases to `ContinuousFileSplitEnumeratorTest`:
   
   - `testPostponeBucketIncrementalSplitAssignedByWriteId` - a postpone bucket 
`IncrementalSplit` is assigned by the write id encoded in the data file name.
   - `testPostponeBucketIncrementalSplitWithoutAfterFiles` - the write id is 
taken from the before files when the diff only removes files.
   - `testIncrementalSplitWithRealBucketAssignedByBucket` - a regular bucket is 
still assigned by its bucket id.
   
   The two postpone cases fail on master with `expected: 1 but was: -2`, 
confirming the stranded assignment, and pass with this change. 
`ContinuousFileSplitEnumeratorTest` (18 tests) and 
`AlignedContinuousFileSplitEnumeratorTest` (3 tests) pass.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


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