Skip to content

[flink] Support consuming historical partition changelog - #4383

Open
luoyuxia wants to merge 1 commit into
apache:mainfrom
luoyuxia:feat/flink-historical-changelog
Open

luoyuxia wants to merge 1 commit into
apache:mainfrom
luoyuxia:feat/flink-historical-changelog

Conversation

@luoyuxia

Copy link
Copy Markdown
Contributor

Purpose

Linked issue: Related to #4371. This PR covers consumption of existing historical partitions; runtime partition retirement remains outside its scope.

Flink currently discovers ordinary partitions only, so changes written through the internal historical partition are invisible to streaming consumers. Subscribe to the existing historical changelog for primary-key tables with historical partition access enabled. Keep original business partition values and apply SQL partition predicates to the records.

Scope and correctness limits

This change assumes that the ordinary partitions being read do not transition to historical partitions while the job runs, including during full startup. This is a usage precondition, not an enforced guard. Long-running jobs on auto-partitioned tables can encounter this boundary.

  • No ordered handoff across retirement: a historical update can be emitted before unread records for the same key in the retiring ordinary bucket, affecting downstream materialization or aggregation. This applies to full and changelog-only startup, including explicit starting offsets. Existing checkpoint recovery does not add a retirement protocol.
  • Existing unread-log loss remains: partition removal already unsubscribes the ordinary bucket without waiting for its backlog to drain. This PR neither introduces nor fixes that behavior, and subscribing to historical logs does not recover the skipped records.
  • Consequently, this PR does not promise complete, ordered incremental consumption across partition retirement. The full-mode hybrid split only coordinates the historical lake baseline planned at startup with its corresponding historical log.

Performance and retention limits

  • Historical business partitions' lake splits are grouped by bucket for full startup. Snapshot parallelism is at most min(historical bucket count, source parallelism); partitions within a bucket are read sequentially. This can reduce snapshot parallelism compared with independently assigned lake splits, and slow snapshots delay log output on the same reader. Changelog-only startup has no additional snapshot grouping cost; it remains subject to the existing per-bucket log parallelism limit.
  • Multiple business partitions share the historical log. Partition predicates may still require reading unrelated business partitions' records before Flink filters them, increasing I/O and filtering work. The existing SQL residual-filter mechanism is unchanged.
  • Existing log retention limits apply. Without a readable lake snapshot, full startup falls back to the earliest retained historical changelog and cannot guarantee a complete baseline when the required history is unavailable.
  • Scope is streaming primary-key tables, within the existing historical feature's support for auto-partitioned Paimon tables with one partition key. This does not extend historical changelog subscription to log tables or batch execution.

Brief change log

  • Resolve the historical partition explicitly through MetadataUpdater after pruning ordinary partitions. Preserve Admin.listPartitionInfos() semantics and bypass KV-snapshot initialization for the historical partition.
  • Use the same readable lake snapshot's data and historical bucket offsets for full startup, reusing LakeSnapshotAndFlussLogSplit and the existing generation and reader paths.
  • Continue past empty lake splits so a filtered-out split cannot finish the snapshot before subsequent splits are read.
  • Keep existing SQL residual filters, split assignment, and checkpoint state formats.

API and Format

No public API, RPC, storage format, split serializer version, or checkpoint state format changes. Admin.listPartitionInfos() continues to list ordinary partitions only.

An old checkpoint from a source without historical subscription has no historical offset. If the historical partition is discovered as new after restoration, the existing discovery rule starts it at the earliest retained offset, which can replay history already represented in downstream state. This PR does not provide checkpoint-upgrade offset migration or deduplication; an unchanged state format is not an upgrade-consistency guarantee.

Documentation

Document historical changelog consumption in website/docs/engine-flink/reads.md, including the retirement ordering limitation, existing unread-log loss, snapshot parallelism tradeoff, shared-log filtering cost, and retention boundary.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Exhausted filtered-empty lake iterators are not closed, and checkpoint-restore behavior lacks regression coverage.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR adds Flink streaming consumption for historical partition changelogs on supported primary-key tables.

Changes:

  • Discovers and subscribes to __historical__ partitions.
  • Groups historical lake snapshots with bucket changelog offsets.
  • Adds scanner, generator, integration, and documentation coverage.
File summaries
File Description
FlinkSourceEnumerator.java Historical partition discovery and split initialization
LakeSplitGenerator.java Historical lake/log hybrid split planning
SeekableLakeSnapshotSplitScanner.java Skips empty lake splits
HistoricalPartitionITCase.java End-to-end historical changelog coverage
LakeSplitGeneratorTest.java Hybrid split unit tests
SeekableLakeSnapshotSplitScannerTest.java Empty-split scanner test
website/docs/engine-flink/reads.md Historical changelog documentation
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +75 to 77
while (currentLakeRecordIterator != null && !currentLakeRecordIterator.hasNext()) {
updateCurrentIterator();
}
Comment on lines +856 to +858
if (streaming
&& hasPrimaryKey
&& tableInfo.getTableConfig().isHistoricalPartitionEnabled()) {
Consume historical changes and pair historical lake snapshots with their
bucket logs. Document retirement and snapshot-parallelism limitations.

Co-Authored-By: Codex <noreply@openai.com>
AI-Model: gpt-6
AI-Contributed/Feature: 56/56
AI-Contributed/UT: 0/0
@luoyuxia
luoyuxia force-pushed the feat/flink-historical-changelog branch from 9c13717 to 454f591 Compare September 17, 2026 09:34
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.

2 participants