Uh oh!
There was an error while loading. Please reload this page.
[refactor](storage) move fixed partial-update fill into FixedPartialUpdateFillStage - #66609
Conversation
hello-stephen
commented
Aug 10, 2026
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
csun5285
commented
Aug 10, 2026
run buildall |
csun5285
commented
Aug 10, 2026
/review |
b946f17 to
8bce819Comparecsun5285
commented
Aug 10, 2026
/review |
There was a problem hiding this comment.
Request changes: one fixed-partial-update hot-path regression remains.
Critical checkpoint conclusions:
- Goal and test proof: The logical fill migration is functionally coherent. New and existing coverage exercises history/default/sequence/delete behavior, exact marks and stats, vertical persistence and PK bytes, multi-segment missing-sequence persistence, and combined sequence/Variant/RowStore persistence. Per the review bundle, I did not run local builds or tests. Current CI has formatting, CheckStyle, license, dependency, and secret checks green; BE UT (Linux/macOS), compile, and performance are still pending.
- Scope: The production change is confined to the fixed-partial-update transform/writer seam and related tests; no unrelated behavior change was found.
- Concurrency and lifecycle: Transform/fetch state is flush-local, shared totals are atomic, delete-bitmap mutations are locked, RowStore generation owns its COW snapshot, and failures after transform remain terminal before rowset commit.
- Config and compatibility: No config, FE/BE variable, protocol, or storage-format contract changes were introduced; no rolling or persisted-data compatibility concern was found.
- Parallel paths and special conditions: Horizontal and vertical writers, flexible updates, row-binlog groups, cloud/transient paths, streaming rejection, compaction, and schema change were traced. Fixed fill runs exactly once on one fresh segment, while specialized paths retain their intended ownership.
- Observability and write correctness: Counters, correctness sentinels, TEMP delete marks, transaction visibility, historical/default fill, supplied and missing sequences, deletes, new-key policy, null/default/auto-increment values, final PK construction, Variant parsing, and RowStore serialization remain coherent.
- Performance: The inline P2 is blocking. Every fixed update now repeats primary-key conversion in the generic writer; no-sequence and supplied-sequence cases also repeat final-key encoding and conditional row-cache erasure.
- Other issues and focus: No additional user focus was supplied, so the whole PR was reviewed. No other distinct issue survived duplicate suppression and two converged review rounds.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Comment-only duplicate-suppressed closeout for this review run.
The current head already has CHANGES_REQUESTED review 4894972388 with inline comment 3747875632 covering the one substantiated P2: fixed partial updates now repeat key conversion in both generic writers, and no-sequence/supplied-sequence cases also repeat final-key encoding plus conditional RowCache erasure. This run independently reached the same finding, then suppressed it under the existing-thread rule. No new distinct inline issue remains after two converged review rounds.
Critical checkpoint conclusions:
- Goal and test proof: The fixed-PU fill migration is functionally coherent. The added tests and unchanged segment-format coverage exercise historical/default fill, sequence winner/loser and omitted/supplied suffixes, delete signs, exact TEMP marks and stats, horizontal/vertical persistence, Variant parsing, and RowStore serialization. Per the review bundle, no local builds or tests were run.
- Scope: The production change is focused on the fixed-PU transform/writer seam and related tests; no unrelated behavior change was found.
- Concurrency and lifecycle: Each successful fixed fill owns one fresh segment at row position zero; concurrent flushes use distinct atomic segment ids and flush-local transform/fetch state. Rowset pins, the RowStore COW snapshot, atomic counters, sticky failure handling, and abort cleanup have consistent lifetimes.
- Configuration and compatibility: No new configuration, FE/BE variable, protocol, storage-format, or rolling-upgrade contract is introduced. Horizontal/vertical selection remains dynamic and both paths were reviewed.
- Parallel and special paths: Flexible partial update, row-binlog/group writers, transient/publish, streaming rejection, compaction, schema change, empty blocks, multi-segment coordinates, and downstream failure paths were traced; no distinct regression survived review.
- Write correctness and observability: MOW lookup outcomes, delete-bitmap marks and sentinels, new-key policy, required/default/nullable/auto-increment fill, old-deleted sequence preservation, final PK construction, row/meta counts, and existing stats/logging remain coherent.
- Performance: The already-landed P2 remains the only blocking concern. It was not duplicated here.
- User focus: No additional review focus was supplied, so the complete PR was reviewed.
Review status: complete and converged; zero new inline comments after live duplicate suppression.
hello-stephen
commented
Aug 10, 2026
TPC-H: Total hot run time: 28952 ms |
hello-stephen
commented
Aug 10, 2026
TPC-DS: Total hot run time: 158519 ms |
hello-stephen
commented
Aug 10, 2026
ClickBench: Total hot run time: 23.84 s |
8bce819 to
5468666Comparecsun5285
commented
Aug 11, 2026
run buildall |
csun5285
commented
Aug 11, 2026
/review |
There was a problem hiding this comment.
Automated review result: no new blocking findings.
Round 1 converged after three normal full-scope reviews and two separate risk-focused reviews all returned NO_NEW_VALUABLE_FINDINGS. I independently verified their conclusions and completed a final sweep over all 15 changed files and the unresolved-candidate list. No new inline comment is warranted. The existing performance thread about repeated fixed-update key conversion/encoding was treated as known context and was not duplicated.
Critical checkpoint conclusions:
- Goal and proof: The PR accomplishes its stated refactor: fixed partial-update loads now run
Validate -> FixedPartialUpdateFill -> VariantParse -> RowStoreFill, and both generic writers receive the same full-width logical row. The focused tests cover history/default fill, sequence win/equal/loss outcomes, delete signs, new-row policies, exact TEMP marks/stats, persisted PK bytes, Variant, and row-store rebuilding. The unchanged golden-format test additionally drives two segments through both horizontal and vertical writers, including an omitted sequence column and a combined sequence/Variant/row-store schema, and compares logical cells, raw row-store values, and PK data with pre-refactor output. - Scope and clarity: The change is focused on moving one duplicated fixed-fill implementation into the transform seam, removing the two writer-owned implementations and adding shared conversion helpers plus targeted tests. No unrelated behavior change was found.
- Concurrency and lifecycle: Each nonempty memtable receives its final unique segment id before submission; one COW block copy is transformed once, and block-local positions remain final segment row ids. Per-transform state is isolated, flusher counters are atomic, and delete-bitmap access is synchronized. Historical rowsets stay pinned through reads; the row-store generator owns a COW snapshot and is consumed synchronously before its source block dies. No new lock-order, deadlock, static-initialization, ownership-cycle, or leak risk was found.
- Data correctness and transactionality: Supplied-sequence probes retain the sequence suffix, omitted-sequence probes remain unsuffixed, and both generic writers build the final PK from the filled sequence. Old-row and losing-new-row TEMP marks, sentinel handling, segcompaction conversion, and publish-time version replacement remain aligned with the prior path. Failures propagate as non-OK status/converted exceptions and terminate the load; no same-block retry can double-apply marks or counters.
- Parallel and compatibility paths: Horizontal and vertical fixed updates, flexible updates, grouped row-binlog writes, transient writers, BetaRowsetWriterV2 rejection, schema change, compaction, and multi-segment flushes were traced. No new configuration, FE-BE variable, function/storage format, persistence-log, or rolling-upgrade compatibility change is introduced.
- Conditions, errors, and observability: Width/context/segment-id validation still fences unsupported paths before fill. Existing tablet/transaction-aware errors, partial-update stats, delete-bitmap summaries, and logs remain sufficient; no new configuration or metric is needed for this internal refactor.
- Performance: The current head invalidates row cache only during final writer key generation. The remaining duplicated key conversion/encoding work is already covered by the existing inline thread, so I did not submit it again. No additional substantiated performance regression was found.
- Validation status: Doris compile, clang-format, and style checks are passing for the reviewed head. BE unit tests and regression jobs were still running at review time. Per the review-runner instructions, I did not run builds or tests locally.
- User focus: No additional user-provided focus was specified; the complete PR was reviewed.
Overall opinion: the refactor is coherent and well covered, with no new critical blocking issue found. Review completion status: converged in round 1, comment-only review, zero new inline comments.
…pdateFillStage; horizontal writer exits the PU business Fourth PR of the apache#64674 split stack (apache#65492, apache#66151, apache#66528). The fixed partial-update fill moves out of both segment writers into the transform chain: fixed PU loads now run [Validate, FixedPartialUpdateFill, VariantParse, RowStoreFill], so the fill widens the narrow block, probes each key via MowKeyProbe::for_partial_update, reads old rows through a per-block HistoricalRowFetcher, and hands the writers a plain full-width upsert. Flexible partial update keeps its [Validate] bridge and stays in the vertical writer until its own stage lands. - storage/transform/partial_update_fill.{h,cpp}: the fixed fill stage (widen -> stage-local RowKeyEncoder/convertor -> probe_and_plan -> fill_missing_columns -> swap). Fault-injection debug point names are kept so the fault_injection_p0 suites keep working. - storage/transform/transform_util.{h,cpp}: key/seq conversion and the narrow-block widening helper, shared with later stages. - SegmentWriter exits partial update entirely: the fill, its preconditions check, the probe wrapper, the row-store serialization body and the PU stats members are deleted; only the flexible NotSupported rejection stays (removed later as an intended change). - VerticalSegmentWriter drops its fixed fill; write_batch dispatches only flexible loads to the in-writer fill, fixed loads take the regular path; batch_block converges to the single full-width check. - The chain's PartialUpdateStats output returns with its first real producer: transform_block folds the probe counters into the flusher totals; the horizontal _flush_segment_writer stats reads are gone. Equivalence pinned by the golden segment-format tests (apache#65977): PartialUpdateAndRowBinlogPathsKeepTheirSegmentBytes now drives the chain fill and still matches the checked-in bytes. 81 BE UTs green, including 13 new FixedPartialUpdateTest branch-coverage cases and two writer-integration cases that read persisted rowsets and the primary key index back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5468666 to
b45ad2aComparecsun5285
commented
Aug 11, 2026
run buildall |
hello-stephen
commented
Aug 11, 2026
TPC-H: Total hot run time: 28992 ms |
hello-stephen
commented
Aug 11, 2026
TPC-DS: Total hot run time: 158369 ms |
hello-stephen
commented
Aug 11, 2026
ClickBench: Total hot run time: 23.95 s |
Uh oh!
There was an error while loading. Please reload this page.
PR approved by at least one committer and no changes requested. |
hello-stephen
commented
Aug 13, 2026
skip check_coverage |
PR approved by anyone and no changes requested. |
yiguolei
commented
Aug 13, 2026
/review |
There was a problem hiding this comment.
Review conclusion: no new blocking correctness issue found; approval opinion, submitted as a comment-only review with zero inline comments.
Critical checkpoint conclusions:
- Goal and proof: the fixed partial-update fill is moved from both segment writers into
[Validate, FixedPartialUpdateFill, VariantParse, RowStoreFill], and the writers receive the same completed full-width row image. The new exact bitmap/stats/error/readback tests and the existing horizontal/vertical multi-segment golden-format cases cover the principal behavior. - Scope and focus: the production change is focused on the transform/writer ownership seam. I reviewed all 15 changed files and the upstream/downstream probe, historical-read, rowset-flush, row-binlog, and primary-key-index paths. No additional user focus was supplied.
- Concurrency: concurrent memtable flushes use per-flush transform state; flusher totals are atomic and delete-bitmap access is internally locked. No new lock ordering, deadlock, or unsafe shared lifetime was found.
- Lifecycle:
HistoricalRowFetcherpins source rowsets through the read, and the RowStore generator owns a COW snapshot until horizontal materialization or vertical bounded generation completes. No cycle, cross-TU static dependency, or premature release was found. - Configuration: no configuration item was added. Both horizontal and vertical writer selections retain fixed-update behavior; flexible updates remain vertical-only.
- Compatibility and parallel paths: no protocol or storage-format change was introduced. Normal/cloud flushes traverse the new fixed fill once; transient, row-binlog, compaction, schema-change, and flexible-update routes neither bypass a required fill nor apply it twice.
- Conditions and errors: segment-id and block-width fences fail explicitly; the fixed path preserves supplied/omitted sequence, delete-sign, new-key, default/null, required-column, and auto-increment behavior. Status and exception boundaries remain checked.
- Data-write correctness: the transform receives the final segment id, starts at physical row 0, and preserves row order/count, so old-row and losing-new-row TEMP delete-bitmap marks retain the correct
{rowset, segment, row}identity. A later writer failure fails the flush token/transaction, preventing publication of the failed rowset and its counters. - Tests and expected results: branch tests assert exact row images, bitmap membership, counters, error policies, sentinel marks, row-store reads, persisted rows, and key encodings. Existing format tests cover two segments, both writer modes, sequence supplied/omitted, Variant, and RowStore. Per runner instructions this was a review-only pass; no build or test command was run.
- Observability and persistence: no new persistent metadata, EditLog, FE/BE variable, or configuration propagation is involved. Existing contextual errors and flush logging remain sufficient for this refactor.
- Performance: the extra fixed-update key conversion/encoding work is already covered by existing discussions r3747875632 and r3763226452 and was not duplicated. I found no additional substantiated performance issue.
- Other issues: none found after the main full-diff sweep, two normal full-review scopes, a separate five-risk seam review, and a final changed-file/unresolved-candidate sweep. All Round 1 agents returned
NO_NEW_VALUABLE_FINDINGS, so the review converged in one round.
Uh oh!
There was an error while loading. Please reload this page.
…pdateFillStage (apache#66609) Fourth PR of the apache#64674 split stack (apache#65492, apache#66151, apache#66528). The fixed partial-update fill moves out of both segment writers into the transform chain: fixed PU loads now run [Validate, FixedPartialUpdateFill, VariantParse, RowStoreFill], so the fill widens the narrow block, probes each key via MowKeyProbe::for_partial_update, reads old rows through a per-block HistoricalRowFetcher, and hands the writers a plain full-width upsert. ### What problem does this PR solve? Issue Number: close #xxx Related PR: #xxx Problem Summary: ### Release note None ### Check List (For Author) - Test <!-- At least one of them must be included. --> - [ ] Regression test - [x] Unit Test - [ ] Manual test (add detailed scripts or steps below) - [ ] No need to test or manual test. Explain why: - [ ] This is a refactor/code format and no logic has been changed. - [ ] Previous test can cover this change. - [ ] No code files have been changed. - [ ] Other reason <!-- Add your reason? --> - Behavior changed: - [ ] No. - [ ] Yes. <!-- Explain the behavior change --> - Does this need documentation? - [ ] No. - [ ] Yes. <!-- Add document PR link here. eg: apache/doris-website#1214 --> ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label <!-- Add branch pick label that this PR should merge into --> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…RowBinlogSegmentWriter (#66883) ### What problem does this PR solve? Related PR: #66774 (stack PR 5/6), #66609 (4/6), #66528 (3/6), #66151 (2/6), #65492 (1/6) Last PR of the block-transform-chain refactor stack, and the one that pays it off: with the binlog derivation in the chain, no segment writer derives or fills anything any more -- both writers are pure storage-format sinks. **`RowBinlogDeriveStage`** : rebuilds the load block into a full-width block over the binlog schema -- key + AFTER values, optional `__BEFORE__*` values, and the TSO / LSN / op columns ### Release note None ### Check List (For Author) - Test <!-- At least one of them must be included. --> - [ ] Regression test - [ ] Unit Test - [ ] Manual test (add detailed scripts or steps below) - [ ] No need to test or manual test. Explain why: - [ ] This is a refactor/code format and no logic has been changed. - [ ] Previous test can cover this change. - [ ] No code files have been changed. - [ ] Other reason <!-- Add your reason? --> - Behavior changed: - [ ] No. - [ ] Yes. <!-- Explain the behavior change --> - Does this need documentation? - [ ] No. - [ ] Yes. <!-- Add document PR link here. eg: apache/doris-website#1214 --> ### Check List (For Reviewer who merge this PR) - [ ] Confirm the release note - [ ] Confirm test cases - [ ] Confirm document - [ ] Add branch pick label <!-- Add branch pick label that this PR should merge into --> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Fourth PR of the #64674 split stack (#65492, #66151, #66528). The fixed partial-update fill moves out of both segment writers into the transform chain: fixed PU loads now run [Validate, FixedPartialUpdateFill, VariantParse, RowStoreFill], so the fill widens the narrow block, probes each key via MowKeyProbe::for_partial_update, reads old rows through a per-block HistoricalRowFetcher, and hands the writers a plain full-width upsert.
What problem does this PR solve?
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
Release note
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)