Skip to content

Conversation

@srlch
Copy link
Contributor

@srlch srlch commented Dec 15, 2025

Summary

Adds tablet-range based pruning for Lake range-distribution tablets across:
Query path (Rowset → SegmentReadOptions.tablet_range → SegmentIterator::_apply_tablet_range), only for shared segments.

PK index compaction path (both serial LakePersistentIndex::major_compact and parallel LakePersistentIndexParallelCompactMgr) via TabletRangeHelper::create_sst_seek_range_from.

Centralizes TabletRangePB parsing in TabletRangeHelper and introduces a standalone SstSeekRange type under lake/, cleaning up includes and ownership between helpers and the compaction manager.

UTs cover single/multi-column PK, inclusive/exclusive bounds, invalid metadata, CHAR/VARCHAR, and both serial/parallel compaction with tablet range filtering.

Fixes #64986

What type of PR is this:

  • BugFix
  • Feature
  • Enhancement
  • Refactor
  • UT
  • Doc
  • Tool

Does this PR entail a change in behavior?

  • Yes, this PR will result in a change in behavior.
  • No, this PR will not result in a change in behavior.

If yes, please specify the type of change:

  • Interface/UI changes: syntax, type conversion, expression evaluation, display information
  • Parameter changes: default values, similar parameters but with different default values
  • Policy changes: use new policy to replace old one, functionality automatically enabled
  • Feature removed
  • Miscellaneous: upgrade & downgrade compatibility, etc.

Checklist:

  • I have added test cases for my bug fix or my new feature
  • This pr needs user documentation (for new or modified features or behaviors)
    • I have added documentation for my new feature or new function
  • This is a backport pr

Bugfix cherry-pick branch check:

  • I have checked the version labels which the pr will be auto-backported to the target branch
    • 4.0
    • 3.5
    • 3.4
    • 3.3

Note

Introduces tablet-range aware pruning for Lake range-distribution tablets and consolidates range parsing.

  • Adds TabletRangeHelper and SstSeekRange to parse TabletRangePB and derive seek/stop keys; wires into build (CMake) and adds TabletMetadataPB.range in proto
  • Query path: adds SegmentReadOptions.tablet_range and SegmentIterator::_apply_tablet_range; Rowset supplies range only for shared segments
  • PK index compaction (serial/parallel): LakePersistentIndex::{prepare_merging_iterator,merge_sstables,major_compact} and LakePersistentIndexParallelCompactMgr restrict input/merge by tablet range when sstables are shared
  • RangeRouter now builds boundaries via TabletRangeHelper and strengthens range validation
  • FE: CreateTableAnalyzer enforces sort keys equal primary key order when range distribution is enabled for PK tables
  • Extensive new tests for single/multi-column keys, inclusive/exclusive bounds, invalid metadata, CHAR/VARCHAR, and compaction

Written by Cursor Bugbot for commit ba85e7b. This will update automatically on new commits. Configure here.

@srlch srlch requested review from a team as code owners December 15, 2025 11:21
@wanpengfei-git wanpengfei-git requested a review from a team December 15, 2025 11:22
@mergify mergify bot assigned srlch Dec 15, 2025
@alvin-celerdata
Copy link
Contributor

@cursor review

Copy link
Contributor

@alvin-celerdata alvin-celerdata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to know how to reuse the same rowset with different seek ranges.

Comment on lines 139 to 155
private:
Status _init_seek_range();

TabletManager* _tablet_mgr;
int64_t _tablet_id;
const RowsetMetadataPB* _metadata;
int _index;
TabletSchemaPtr _tablet_schema;
TabletMetadataPtr _tablet_metadata;
std::vector<SegmentSharedPtr> _segments;
bool _parallel_load;
// only takes effect when rowset is overlapped, tells how many segments will be used in compaction,
// default is 0 means every segment will be used.
// only used for compaction
size_t _compaction_segment_limit;
// represents the seek range of the rowset, this member is only used for range distribution table
std::unique_ptr<SeekRange> _seek_range;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be a significant change for Rowset.
Before this change, the rowset could be reused for all requests because every reader would have the same range.
But when a rowset has a range, it becomes hard to reuse, especially when you are trying to record the seek range in this class.
If a rowset will be reused for different ranges, how do you differentiate the various ranges for the same rowset?
I will set a request change before we have an alignment on how you are going to handle it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have remove the _seek_range from rowset and rename it to avoid ambiguity. _seek_range means tablet_range which is a immutable property for a range distribution tablet. tablet_range is totally different from the query range. It means that even a rowset is reused by different reader with different query ranges, this rowset must belong to the same tablet so all reader share this rowset must satisfy the same tablet_range to meet the tablet definition

@srlch srlch force-pushed the segment_tablet_range branch from 2a0eb99 to 9e26d29 Compare December 16, 2025 08:57
@srlch srlch requested a review from a team as a code owner December 16, 2025 08:57
@alvin-celerdata
Copy link
Contributor

@cursor review

@alvin-celerdata
Copy link
Contributor

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no bugs!

@alvin-celerdata
Copy link
Contributor

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no bugs!

@srlch srlch force-pushed the segment_tablet_range branch from ee64c88 to f222e99 Compare December 23, 2025 07:39
@srlch srlch requested a review from a team as a code owner December 23, 2025 07:39
@srlch srlch changed the title [Feature] Add tablet range pruning for range-distribution Lake tables when reading shared segments [Feature] Add tablet range pruning for range-distribution Lake tables for shared segments and sstables. Dec 23, 2025
@srlch srlch requested a review from a team as a code owner December 23, 2025 08:27
@github-actions
Copy link

[BE Incremental Coverage Report]

fail : 11 / 27 (40.74%)

file detail

path covered_line new_line coverage not_covered_line_detail
🔵 src/storage/rowset/segment_options.cpp 0 3 00.00% [73, 75, 77]
🔵 src/storage/seek_range.h 0 2 00.00% [42, 43]
🔵 src/storage/rowset/segment_iterator.cpp 11 22 50.00% [1159, 1165, 1170, 1171, 1172, 1176, 1177, 1178, 1179, 1182, 1183]

@alvin-celerdata
Copy link
Contributor

@cursor review

@srlch srlch force-pushed the segment_tablet_range branch from 0a583c1 to b40a582 Compare December 24, 2025 05:35
@alvin-celerdata
Copy link
Contributor

@cursor review

@alvin-celerdata
Copy link
Contributor

@cursor review

return Status::InternalError(
fmt::format("Sort key index {} must be the same as pk key index {}", i, sort_key_idxes[i]));
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing runtime check for sort_key_idxes bounds access

The code uses DCHECK_EQ(sort_key_idxes.size(), tablet_schema->num_key_columns()) at line 169, but DCHECK only runs in debug builds. The loop at line 172 then iterates up to num_key_columns() and accesses sort_key_idxes[i] at line 173. In release builds, if sort_key_idxes.size() < num_key_columns() (due to data corruption or older data), this would cause an out-of-bounds vector access with undefined behavior. While the FE analyzer validates this constraint for new tables, the runtime check relies only on a debug assertion.

Fix in Cursor Fix in Web

@srlch srlch force-pushed the segment_tablet_range branch from 22a39aa to ba85e7b Compare December 26, 2025 02:08
@alvin-celerdata
Copy link
Contributor

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no bugs!

@github-actions
Copy link

[Java-Extensions Incremental Coverage Report]

pass : 0 / 0 (0%)

@github-actions
Copy link

[FE Incremental Coverage Report]

fail : 4 / 6 (66.67%)

file detail

path covered_line new_line coverage not_covered_line_detail
🔵 com/starrocks/sql/analyzer/CreateTableAnalyzer.java 4 6 66.67% [489, 497]

… for shared segments and sstables.

Signed-off-by: srlch <[email protected]>
Signed-off-by: srlch <[email protected]>
Signed-off-by: srlch <[email protected]>
@srlch srlch force-pushed the segment_tablet_range branch from ba85e7b to bc01377 Compare December 29, 2025 03:13
@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New multi-tenant data management

5 participants