Skip to content

[FLINK-40339][table] Do not read buffer entries after removing them - #28933

Merged
gustavodemorais merged 1 commit into
apache:masterfrom
confluentinc:FLINK-40339
Aug 6, 2026
Merged

[FLINK-40339][table] Do not read buffer entries after removing them#28933
gustavodemorais merged 1 commit into
apache:masterfrom
confluentinc:FLINK-40339

Conversation

@gustavodemorais

@gustavodemorais gustavodemorais commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of the change

WatermarkCompactingSinkMaterializer removed buffer entries while iterating and read their values afterwards. The value of a Map.Entry is undefined once the entry has been removed, and RocksDBMapEntry returns null for it, so consolidation on restore only works because the heap backend keeps removed values readable.

Brief change log

  • Consume all buffered values in consolidateBufferToMinValue before mutating the buffer, and drop it with a single clear()
  • Iterate values() instead of entries() in the ordered branch

Verifying this change

  • WatermarkCompactingSinkMaterializerTest tests working
  • Our only state backend that tests this code is heap which already worked accidently. Didn’t find a clean way to add additional testing without a adding a load of bloat but the current tests passing is a good coverage

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): no
  • The serializers: no
  • The runtime per-record code paths (performance sensitive): no - consolidation runs at most once per key per restore
  • Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Kubernetes/Yarn, ZooKeeper: no
  • The S3 file system connector: no

Documentation

  • Does this pull request introduce a new feature? no
  • If yes, how is the feature documented? not applicable

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

2.1.220 (Claude Code) with Opus 5

@flinkbot

flinkbot commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands The @flinkbot bot supports the following commands:
  • @flinkbot run azure re-run the last Azure build

}

// Clear only after all values were read.
buffer.clear();

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.

This is simpler indeed, but RocksDB opens a new iterator here IIRC.
Opening an iterator is quite expensive, so this might cause a performance regression.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the branch for the unordered state backends - so Rocksdb is not affected by the change. Currently in open source, only heap backend uses this path. I don't have a strong opinion though, if you think the delete strategy is safer, I can go with that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ops, that is not correct. I just went with the delete approach which means also less changes

The value of a Map.Entry is undefined once the entry has been removed, and
RocksDBMapEntry returns null for it. consolidateBufferToMinValue removed the
entries while iterating and read their values afterwards, which only works
because the heap backend keeps them readable.

Copy every entry before removing it. The key is copied as well because the
entries are sorted by timestamp afterwards.

This is hardening, no behaviour changes on the backends Flink ships: heap is
the only unordered one, and RocksDB and ForSt take the ordered branch that
already read the value before removing.

@rkhachatryan rkhachatryan 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.

LGTM

@geeknarrator geeknarrator 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.

LGTM. Should we add a test for this? I don't think it is covered by existing test, is it?

@gustavodemorais

Copy link
Copy Markdown
Contributor Author

Hey @geeknarrator, our only state backend that tests this code is heap which already worked accidentally. Didn’t find a clean way to add additional testing without a adding a load of bloat but the current tests passing is a good coverage. If you have a good/clean suggestion on how to test this, let me know

@gustavodemorais
gustavodemorais merged commit 79b4843 into apache:master Aug 6, 2026
@gustavodemorais
gustavodemorais deleted the FLINK-40339 branch August 6, 2026 15:56
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.

4 participants