This is an automated email from the ASF dual-hosted git repository. hanahmily pushed a commit to branch fix/ttl-filter-metadata-path in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git
commit cb635d22d225dfe685c1cedcf7318f7a403e1a82 Author: Hongtao Gao <[email protected]> AuthorDate: Thu Jun 11 05:11:15 2026 +0000 Fix TTL filter bypassed on metadata/listing query paths The TTL deadline filter in SelectSegments was gated on reopenClosed=true, so all metadata and stats listing call sites (which pass reopenClosed=false to avoid reopening cold segments) received fully expired segments until the next retention cron run. Drop the !reopenClosed bypass condition so the filter applies regardless of whether the caller intends to reopen closed segments. DecRef accounting is safe: segments filtered out were either CAS-bumped exactly once (DecRef balances it) or unbumped dormant segments (DecRef is a no-op at refCount<=0). The existing reopenClosed=true tests are unaffected. Add TestSelectSegmentsRetention/metadata_path_excludes_fully_expired_segments to guard the metadata path against regression. --- banyand/internal/storage/tsdb.go | 2 +- banyand/internal/storage/tsdb_test.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/banyand/internal/storage/tsdb.go b/banyand/internal/storage/tsdb.go index ae3275d04..4c4dc83ac 100644 --- a/banyand/internal/storage/tsdb.go +++ b/banyand/internal/storage/tsdb.go @@ -279,7 +279,7 @@ func (d *database[T, O]) SelectSegments(timeRange timestamp.TimeRange, reopenClo return nil, nil } segments, err := d.segmentController.selectSegments(timeRange, reopenClosed) - if err != nil || !reopenClosed || d.disableRetention { + if err != nil || d.disableRetention { return segments, err } // Exclude segments whose whole time range has already passed the retention diff --git a/banyand/internal/storage/tsdb_test.go b/banyand/internal/storage/tsdb_test.go index e2ac247f8..12e551792 100644 --- a/banyand/internal/storage/tsdb_test.go +++ b/banyand/internal/storage/tsdb_test.go @@ -283,6 +283,19 @@ func TestSelectSegmentsRetention(t *testing.T) { }() require.Len(t, segs, 2) }) + + t.Run("metadata path excludes fully expired segments", func(t *testing.T) { + tsdb := newDB(t, false) + segs, err := tsdb.SelectSegments(wide, false) + require.NoError(t, err) + defer func() { + for _, s := range segs { + s.DecRef() + } + }() + require.Len(t, segs, 1, "fully expired segment must be filtered out for reopenClosed=false too") + require.False(t, segs[0].GetTimeRange().Before(deadline), "the kept segment must not be fully expired") + }) } func TestTakeFileSnapshot(t *testing.T) {
