Skip to content

KAFKA-20732: seed highestOffsetInRemoteStorage before size-based remote retention [4.1]#22737

Open
horkyada wants to merge 1 commit into
apache:4.1from
horkyada:KAFKA-20732-backport-4.1
Open

KAFKA-20732: seed highestOffsetInRemoteStorage before size-based remote retention [4.1]#22737
horkyada wants to merge 1 commit into
apache:4.1from
horkyada:KAFKA-20732-backport-4.1

Conversation

@horkyada

@horkyada horkyada commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Backport of #22661 to the 4.1 branch (already merged to trunk and 4.3.2).

Problem

On a freshly elected leader of a tiered partition, size-retention can run while highestOffsetInRemoteStorage is still -1 — it is seeded only by the copy and follower tasks, which race the expiration task. UnifiedLog.onlyLocalLogSegmentsSize() then filters baseOffset >= -1 and counts the entire local log, which is also counted in remoteLogSizeBytes for the same offsets. Apparent size roughly doubles, a false retention.bytes breach fires, and in-retention data is deleted from the remote tier and — via the resulting logStartOffset advance replicated to followers — the local tier on all replicas. The follower path already guards this (RLMFollowerTask.execute()); the leader/expiration path did not.

Fix

In cleanupExpiredRemoteLogSegments, when highestOffsetInRemoteStorage() == -1, seed it from remote metadata (findHighestRemoteOffset) before computing size-retention. No-op once already seeded.

Note: this also widens UnifiedLog.highestOffsetInRemoteStorage() from package-private to public. trunk and 4.3 already have it public; the == -1 guard requires it.

Testing

Ported the trunk regression test to 4.1's RemoteLogManagerTest harness. Verified RED without the fix (both copied segments deleted, logStartOffset -> 200) and GREEN with it; full RemoteLogManagerTest passes.

…te retention

Backport of apache#22661 (merged to trunk and 4.3.2) to 4.1. On a freshly-elected tiered-partition leader, RLMExpirationTask can run size-retention while highestOffsetInRemoteStorage is still -1 (seeded only by the copy and follower tasks, which race it); onlyLocalLogSegmentsSize then counts the whole local log, double-counted with remoteLogSizeBytes, producing a false retention.bytes breach that deletes in-retention data from both tiers. Mirror the follower path: seed it from remote metadata before size-retention (no-op once seeded).

Also widens UnifiedLog.highestOffsetInRemoteStorage() to public, which trunk/4.3 already have and which the guard requires. Regression test ported to the 4.1 harness (RED without the fix, GREEN with it).
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