Skip to content

[Bug] IndexStoreService.queryAsync misses index files due to incorrect time range subMap selection #10268

@lizhimins

Description

@lizhimins

Before Creating the Bug Report

  • I found a bug, not just asking a question, which should be created in GitHub Discussions.
  • I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.
  • I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.

Runtime platform environment

Linux

RocketMQ version

master branch, tieredstore module

JDK Version

JDK 8+

Describe the Bug

In IndexStoreService.queryAsync() (tieredstore/src/main/java/org/apache/rocketmq/tieredstore/index/IndexStoreService.java), the file selection logic uses:

ConcurrentNavigableMap<Long, IndexFile> pendingMap =
    this.timeStoreTable.subMap(beginTime, true, endTime, true);

This is incorrect because timeStoreTable uses each IndexFile's begin time as its key. The subMap(beginTime, endTime) query only returns files whose begin time falls within [queryBeginTime, queryEndTime].

Two time intervals overlap if and only if:

file.beginTime <= query.endTime  &&  file.endTime >= query.beginTime

The current code only checks whether file.beginTime is within the query range, which means any file whose beginTime is before queryBeginTime (but whose endTime still covers part or all of the query range) will be silently excluded.

Example:

File A: beginTime=1770792994354, endTime=1776162863167
Query:  beginTime=1773804163000, endTime=1776109687001

subMap(1773804163000, true, 1776109687001, true) returns EMPTY
because File A's key (1770792994354) < query beginTime (1773804163000).
But File A fully covers the query range and SHOULD be queried.

Steps to Reproduce

  1. Enable tiered store and let IndexStoreService accumulate multiple index files with different time ranges.
  2. Query index with a time range where queryBeginTime is later than some file's beginTime but earlier than its endTime.
  3. The query returns empty or incomplete results because that file is excluded at the subMap level, even though the file's time range overlaps with the query.

What Did You Expect to See?

The query should return all IndexItems from any IndexFile whose time range overlaps with the requested [beginTime, endTime].

What Did You See Instead?

Files whose beginTime is less than queryBeginTime are silently excluded, even if they fully contain the query range. This leads to missing or empty query results.

Additional Context

The fix should change the file selection logic to:

ConcurrentNavigableMap<Long, IndexFile> pendingMap =
    this.timeStoreTable.headMap(endTime, true);

for (Map.Entry<Long, IndexFile> entry : pendingMap.descendingMap().entrySet()) {
    if (entry.getValue().getEndTimestamp() < beginTime) {
        break;
    }
    // queryAsync...
}
  • headMap(endTime, true) selects all files with beginTime <= queryEndTime.
  • During descending iteration, break early when file.endTime < queryBeginTime — since files are sorted by beginTime descending, all remaining older files will also fail this check, enabling early termination.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions