From 4388b5dfddba44538ecf5d1746493b531cf981da Mon Sep 17 00:00:00 2001 From: yangxuan Date: Thu, 26 Mar 2026 19:59:03 +0800 Subject: [PATCH] fix: filter deleted indexes in GetIndexedSegments to prevent stale segment loading GetIndexedSegments included deleted index entries in targetIndices but skipped them in the counting loop, causing indexedFields to never equal len(targetIndices) when deleted entries existed. This made every segment appear unindexed after drop+create index cycles, forcing GetQueryVChanPositions to fall back to loading stale pre-compaction segments instead of the optimized one. pr: #48558 See also: #48557 Signed-off-by: yangxuan --- internal/datacoord/index_meta.go | 6 +----- internal/datacoord/index_meta_test.go | 29 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/internal/datacoord/index_meta.go b/internal/datacoord/index_meta.go index 36589231b813d..e6d5e83c5ad2a 100644 --- a/internal/datacoord/index_meta.go +++ b/internal/datacoord/index_meta.go @@ -562,7 +562,7 @@ func (m *indexMeta) GetIndexedSegments(collectionID int64, segmentIDs, fieldIDs matchedFields := typeutil.NewUniqueSet() targetIndices := lo.Filter(lo.Values(fieldIndexes), func(index *model.Index, _ int) bool { - return fieldIDSet.Contain(index.FieldID) + return fieldIDSet.Contain(index.FieldID) && !index.IsDeleted }) for _, index := range targetIndices { matchedFields.Insert(index.FieldID) @@ -576,10 +576,6 @@ func (m *indexMeta) GetIndexedSegments(collectionID int64, segmentIDs, fieldIDs checkSegmentState := func(indexes *typeutil.ConcurrentMap[UniqueID, *model.SegmentIndex]) bool { indexedFields := 0 for _, index := range targetIndices { - if !fieldIDSet.Contain(index.FieldID) || index.IsDeleted { - continue - } - if segIdx, ok := indexes.Get(index.IndexID); ok && segIdx.IndexState == commonpb.IndexState_Finished { indexedFields += 1 } diff --git a/internal/datacoord/index_meta_test.go b/internal/datacoord/index_meta_test.go index 49e7f7f388cf3..bffb710a7a0ca 100644 --- a/internal/datacoord/index_meta_test.go +++ b/internal/datacoord/index_meta_test.go @@ -816,6 +816,35 @@ func TestMeta_GetIndexedSegment(t *testing.T) { segments := m.GetIndexedSegments(collID+1, []int64{segID}, []int64{fieldID}) assert.Len(t, segments, 0) }) + + t.Run("with deleted index entries", func(t *testing.T) { + // Simulate drop+create index cycles: add deleted index entries for the same field. + // Previously, deleted entries inflated len(targetIndices), causing the indexed check + // to always fail (indexedFields=1 != len(targetIndices)=N). + deletedIndexID1 := indexID + 100 + deletedIndexID2 := indexID + 200 + m.indexes[collID][deletedIndexID1] = &model.Index{ + CollectionID: collID, + FieldID: fieldID, + IndexID: deletedIndexID1, + IndexName: "old_idx_1", + IsDeleted: true, + } + m.indexes[collID][deletedIndexID2] = &model.Index{ + CollectionID: collID, + FieldID: fieldID, + IndexID: deletedIndexID2, + IndexName: "old_idx_2", + IsDeleted: true, + } + + segments := m.GetIndexedSegments(collID, []int64{segID}, []int64{fieldID}) + assert.Len(t, segments, 1, "segment should be indexed even with deleted index entries") + + // Cleanup + delete(m.indexes[collID], deletedIndexID1) + delete(m.indexes[collID], deletedIndexID2) + }) } func TestMeta_MarkIndexAsDeleted(t *testing.T) {