Skip to content

[core] Support row-count based data file rolling (target-file-num-rows)#8739

Draft
XiaoHongbo-Hope wants to merge 1 commit into
apache:masterfrom
XiaoHongbo-Hope:de_row_rolling
Draft

[core] Support row-count based data file rolling (target-file-num-rows)#8739
XiaoHongbo-Hope wants to merge 1 commit into
apache:masterfrom
XiaoHongbo-Hope:de_row_rolling

Conversation

@XiaoHongbo-Hope

@XiaoHongbo-Hope XiaoHongbo-Hope commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Purpose

Files roll by size only. On data-evolution tables with very wide rows (e.g.
vector/embedding columns), a size-bounded file still holds too many rows, so a later
add-column / update-by-row-id OOMs materializing that row range. Lance handles this
with max_rows_per_file; this adds the same to Paimon.

  • New option target-file-num-rows (default Long.MAX_VALUE, disabled). Rolls on row
    count or target-file-size, whichever first; bundle-granular.
  • Wired through the append write path (incl. the dedicated BLOB/vector writer) and PK
    data + changelog writers, so data-evolution base writes roll into row-bounded files.
  • Append / bucketed / clustering compaction treat a file at either target (bytes or rows)
    as complete, so a row-capped byte-small file isn't re-selected forever; files with a
    deletion vector are still compacted.

Scope: this PR bounds the DE write path. DE compaction still merges into a
single file — emitting multiple row-bounded files also needs the deletion-vector rewriter
to support multi-output and a row-aware DE planner, left as a follow-up.

Tests

New test methods added in this PR:

  • RollingFileWriterTest#testRollingByRows, #testRollingByRowsWithBundle
  • DedicatedFormatRollingFileWriterTest#testRollingByRows
  • DataEvolutionTableTest#testDataEvolutionWriteRollsByRows, #testDataEvolutionReadWithRolledColumns
  • AppendOnlySimpleTableTest#testCompactionRespectsRowLimit
  • AppendCompactCoordinatorTest#testFilesAtRowCapAreNotRecompacted
  • BucketedAppendCompactManagerTest#testRowCompleteFilesAreNotPicked
  • FullCompactTaskTest#testRowCompleteFilesAreNotFullCompacted

@XiaoHongbo-Hope
XiaoHongbo-Hope force-pushed the de_row_rolling branch 3 times, most recently from af59abf to db36b3a Compare July 22, 2026 10:35
Files roll by size only today. On data-evolution tables with very wide rows
(e.g. vector/embedding columns), a size-bounded file still holds too many rows,
so a later add-column / update-by-row-id OOMs materializing that row range.
Lance handles this with max_rows_per_file; this adds the same to Paimon.

- New option target-file-num-rows (default Long.MAX_VALUE, disabled). Rolling
  triggers on row count or target-file-size, whichever first; bundle-granular.
- Wired through the append write path (incl. the dedicated BLOB/vector writer)
  and the PK data + changelog writers. Data-evolution base writes therefore roll
  into row-bounded files, so a later add-column materializes bounded ranges.
- Append, bucketed and clustering compaction selection treat a file that reached
  either target (bytes or rows) as complete, so a row-capped byte-small file is
  not re-selected forever; files with a deletion vector are still compacted.
- Fail fast on non-positive target-file-num-rows; regenerate docs.

Data-evolution compaction still merges into a single file for now: making it emit
multiple row-bounded files also needs the deletion-vector rewriter to support
multi-output and the DE compaction planner to be row-aware, which is left as a
follow-up. This PR bounds the data-evolution write path.

Tests cover the write primitive, bundle granularity, dedicated writer, DE write
rolling and a rolled base + rolled column stitched read, and no-progress
avoidance in the append, bucketed (incl. full compaction) coordinators.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant