Skip to content

[v25.3.x] [CORE-13340] kafka: fix OffsetForLeaderEpoch for term outside cloud coverage#31075

Open
vbotbuildovich wants to merge 3 commits into
redpanda-data:v25.3.xfrom
vbotbuildovich:ai-backport-pr-31060-v25.3.x-1783736182
Open

[v25.3.x] [CORE-13340] kafka: fix OffsetForLeaderEpoch for term outside cloud coverage#31075
vbotbuildovich wants to merge 3 commits into
redpanda-data:v25.3.xfrom
vbotbuildovich:ai-backport-pr-31060-v25.3.x-1783736182

Conversation

@vbotbuildovich

Copy link
Copy Markdown
Collaborator

Backport of PR #31060

  • Command: git cherry-pick -x 26ba0f2 f620e15 619d0fc
  • Commits backported: 3
  • Conflicts resolved: 1
  • Commits skipped (already on target): 0
  • Backport branch: ai-backport-pr-31060-v25.3.x-1783736182

Conflict details

  • f620e15 (src/v/cluster/archival/tests/BUILD): dependency-list conflict — the target branch already carries //src/v/net and //src/v/net:types where the incoming commit adds //src/v/raft; kept all three in alphabetical order.
  • f620e15 (src/v/cluster/archival/tests/ntp_archiver_test.cc): include-list conflict — the target branch has model/record_batch_types.h and net/types.h where the incoming commit adds raft/consensus.h; kept all includes in alphabetical order.

A getter for the highest term present in cloud storage (whether that be
in the most recent segment, or spillover).

(cherry picked from commit 26ba0f2)
`get_leader_epoch_last_offset_unbounded()` consults cloud storage when
the requested term falls below the first local term.
`get_cloud_term_last_offset()` returns `std::nullopt` both when:

1. The term is older than the oldest term in cloud storage
2. The term is higher than the highest term in cloud storage

The fallback path assumes only case 1. is possible and always returns
the cloud start offset.

For case 2, when a term's data lives only in the local log but the local
start offset has advanced ahead of the cloud upload watermark (e.g. a
raft snapshot taken during partition movement), the term is newer than
everything in cloud storage. Returning the cloud start offset then
reports an offset below the consumer's position, which the consumer
interprets as log truncation and resets to the beginning of the log,
re-consuming all data.

For an example of this case:

1. A partition whose cloud manifest holds only term 1
2. The local start offset advances to term 3
3. Term 2 is present in neither cloud storage nor the local log.

Presently, querying the last offset for the term 2 leader would return
the cloud start offset, when it should return the first local offset
(the start of the next highest term, i.e. term 3).

Fall back to the first local offset (the start of the next-highest term)
in that case, mirroring the non-cloud branch. Read replicas keep
returning the cloud start offset since they have no local log to fall
back on.

(cherry picked from commit f620e15)
…offset`

`get_leader_epoch_last_offset_unbounded()` branched on `is_read_replica`
five times. A read replica serves all reads from cloud storage and never
consults the local log, so handle it in a single early-return block at the
top and drop the `is_read_replica` qualifiers from the rest of the function.

No behavior change.

(cherry picked from commit 619d0fc)
@vbotbuildovich vbotbuildovich added this to the v25.3.x-next milestone Jul 11, 2026
@vbotbuildovich vbotbuildovich added the kind/backport PRs targeting a stable branch label Jul 11, 2026
@vbotbuildovich

Copy link
Copy Markdown
Collaborator Author

CI test results

test results on build#86987
test_status test_class test_method test_arguments test_kind job_url passed reason test_history
FLAKY(PASS) RecoveryModeTest test_recovery_mode null integration https://buildkite.com/redpanda/redpanda/builds/86987#019f4f1a-b5eb-4a29-be6b-30b7eb5c7d02 10/11 Test PASSES after retries.No significant increase in flaky rate(baseline=0.0000, p0=1.0000, reject_threshold=0.0100. adj_baseline=0.1000, p1=0.3487, trust_threshold=0.5000) https://redpanda.metabaseapp.com/dashboard/87-tests?tab=142-dt-individual-test-history&test_class=RecoveryModeTest&test_method=test_recovery_mode

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

Labels

area/build area/redpanda kind/backport PRs targeting a stable branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants