StiffCoconut opened a new issue, #11498:
URL: https://github.com/apache/rocketmq/issues/11498

   ### Runtime platform environment
   Linux ARM64 (Kylin); isolated boundary probe also run on Windows x64.
   
   ### RocketMQ version
   5.5.1, using the official 5.5.1 store JAR. The deployed Proxy has an 
unrelated null-Settings guard; no Broker/store code was modified.
   
   ### JDK Version
   Production: JDK 17.0.19. Local isolated probe: JDK 17.0.18.
   
   ### Describe the Bug
   The scheduled `TimerMessageStore.checkAndReviseMetrics()` can emit a 
misleading `Offset not matched` warning when the timer wheel has no eligible 
slot but a TimerLog mapped file still exists.
   
   Sanitized observed log:
   ```text
   WARN TimerScheduledThread1 - Offset not matched. Request offset: 
9223372036854775807, firstOffset: 0, lastOffset: 104857600, mappedFileSize: 
104857600, mappedFiles count: 1
   ```
   We observed one warning on each of four Broker processes during the same 
scheduled metrics-check window. Immediately following logs showed the metric 
count for `rmq_sys_REVIVE_LOG_DefaultCluster` revised from 0 to 0, and the task 
completed in 31–41 ms. Timer processing queues and offset backlog were zero 
around that window. We have not observed message loss or a delivery stall 
caused by this warning.
   
   ### Root cause analysis
   1. `TimerWheel.checkPhyPos(readTimeMs, 0)` initializes `minFirst` to 
`Long.MAX_VALUE` and returns that sentinel when no matching slot is found.
   2. `checkAndReviseMetrics()` passes this result directly to 
`timerLog.getWholeBuffer(currOffsetPy)` without checking the sentinel.
   3. `MappedFileQueue.findMappedFileByOffset` logs the out-of-range warning 
and returns null.
   4. The metrics scan breaks and performs its usual metrics update.
   
   ### Steps to Reproduce
   The following is a minimal, local-only probe of the boundary call chain, not 
a full Broker integration test. No Producer or Consumer is started. Run with 
the official 5.5.1 libraries:
   ```java
   Path root = Files.createTempDirectory("timer-offset-probe-");
   TimerWheel wheel = new TimerWheel(root.resolve("timerwheel").toString(), 16, 
1000);
   TimerLog log = new TimerLog(root.resolve("timerlog").toString(), 104857600);
   // Allocate a local file to represent retained TimerLog storage.
   log.getMappedFileQueue().getLastMappedFile(0);
   long now = System.currentTimeMillis() / 1000 * 1000;
   long offset = wheel.checkPhyPos(now, 0);
   assert offset == Long.MAX_VALUE;
   assert log.getWholeBuffer(offset) == null;
   // With the store-error logger enabled, the lookup emits the warning above.
   wheel.shutdown();
   log.getMappedFileQueue().shutdown(1000);
   ```
   A local probe with an allocated TimerLog and an empty wheel confirmed the 
sentinel/null-lookup behavior. A subsequent valid-slot lookup still succeeded. 
Production logs supply the full scheduled-task observation.
   
   ### Expected behavior
   An empty eligible timer-wheel range should be handled explicitly without 
attempting a file lookup at `Long.MAX_VALUE` and without an alarming 
out-of-range warning. Preserve the existing metrics reconciliation semantics.
   
   ### Suggested direction
   Guard the sentinel before entering the scan loop. Avoid an unconditional 
early return from the entire method if that would skip the intended zero-count 
metrics reconciliation. Add empty-wheel and valid-slot regression coverage.
   
   ### Related reports checked
   - #9947 / #9948: BLANK record / BufferUnderflowException.
   - #10165: metrics overwritten after timer-engine switch.
   - #10668: stale TimerLog references after CommitLog truncation.
   These appear to have different triggers from this empty-range sentinel case. 
Searches for `Offset not matched`, `checkAndReviseMetrics`, `checkPhyPos`, and 
`9223372036854775807` did not find an exact duplicate.
   
   ### Source references
   - 
https://github.com/apache/rocketmq/blob/rocketmq-all-5.5.1/store/src/main/java/org/apache/rocketmq/store/timer/TimerWheel.java
   - 
https://github.com/apache/rocketmq/blob/rocketmq-all-5.5.1/store/src/main/java/org/apache/rocketmq/store/timer/TimerMessageStore.java
   - 
https://github.com/apache/rocketmq/blob/rocketmq-all-5.5.1/store/src/main/java/org/apache/rocketmq/store/timer/TimerLog.java
   - 
https://github.com/apache/rocketmq/blob/rocketmq-all-5.5.1/store/src/main/java/org/apache/rocketmq/store/MappedFileQueue.java
   
   The same unguarded scan entry is present in develop at 
592d59d12db356f8c98332d9e355a89d92590db3.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to