[ISSUE #10668] Handle stale Timer references after CommitLog truncation - #10741
Open
btlqql wants to merge 1 commit into
Open
[ISSUE #10668] Handle stale Timer references after CommitLog truncation#10741btlqql wants to merge 1 commit into
btlqql wants to merge 1 commit into
Conversation
btlqql
marked this pull request as ready for review
August 1, 2026 13:57
RockteMQ-AI
approved these changes
Aug 1, 2026
RockteMQ-AI
left a comment
Contributor
There was a problem hiding this comment.
Review by github-manager-bot
Summary
Fixes a data integrity gap where TimerMessageStore could retain stale references after CommitLog truncation. Adds truncation notification from DefaultMessageStore, drains/filters stale timer requests, clamps cursor offsets, validates timer messages before enqueue/dequeue, and adds bounds checking to getMessageByCommitOffset.
Findings
- [Info]
DefaultMessageStore.java:806-808— Null-guarded notification toTimerMessageStoreafter truncation is correctly placed afterrecoverTopicQueueTable()and before reput service restart. Good integration point. - [Info]
TimerMessageStore.java:1129-1163—onCommitLogDispatchTruncatecorrectly handles three queues:enqueuePutQueue/dequeuePutQueue: drained viadiscardTruncatedRequests, stale requests released withidempotentRelease(false)dequeueGetQueue: drained list-by-list, filtered, and re-offered- Cursor clamping:
currQueueOffsetandcommitQueueOffsetare clamped to valid range, then checkpointed
- [Info]
TimerMessageStore.java:1213-1218— Bounds check ingetMessageByCommitOffsetavoids unnecessary retry loops when offset is clearly outside CommitLog range. Good performance optimization. - [Info]
TimerMessageStore.java:1231-1245—isValidTimerMessagevalidates topic, real topic, and real queue ID. Package-private visibility enables direct unit testing. - [Info] Enqueue/dequeue paths now skip invalid timer messages with warning logs instead of processing potentially corrupted data.
- [Info] Tests cover both message validation and truncation cleanup scenarios.
Minor Observations
- [Info]
TimerMessageStore.java:1141-1152— The drain-and-reoffer pattern ondequeueGetQueueis not atomic. If another thread adds items between drain and reoffer, those items could be temporarily invisible. In practice, this queue is likely only accessed by the dequeue thread, so this should be safe. Worth a comment for future maintainers. - [Info]
TimerMessageStore.java:1215—offsetPy > maxPhyOffset - sizePycould theoretically underflow ifmaxPhyOffset < sizePy, but this should never happen with a valid CommitLog. No action needed.
Assessment
Solid fix for a real data integrity issue. The approach is thorough — covering notification, cleanup, validation, and bounds checking. Well-tested.
Automated review by github-manager-bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is changed
TimerMessageStoreafterDefaultMessageStoretruncation and clamp its consume-queue cursor.Why
After CommitLog truncation, TimerLog entries can still reference offsets that are gone or later overwritten. The timer pipeline could repeatedly retry those requests and prevent dequeue progress.
Tests
mvn -pl store -am -DskipTests ... compilemvn -pl store -am -Dtest=TimerMessageStoreTest -DfailIfNoTests=false ... testgit diff --checkFixes #10668