diff --git a/internal/datacoord/index_meta.go b/internal/datacoord/index_meta.go index 982bd6769f..26ba99b804 100644 --- a/internal/datacoord/index_meta.go +++ b/internal/datacoord/index_meta.go @@ -519,12 +519,17 @@ func (m *indexMeta) GetSegmentIndexState(collID, segmentID UniqueID, indexID Uni } m.fieldIndexLock.RLock() - fieldIndexes, ok := m.indexes[collID] + fieldIndexesMap, ok := m.indexes[collID] if !ok { state.FailReason = fmt.Sprintf("collection not exist with ID: %d", collID) m.fieldIndexLock.RUnlock() return state } + // Copy the map to avoid data race after releasing the lock + fieldIndexes := make(map[UniqueID]*model.Index, len(fieldIndexesMap)) + for id, index := range fieldIndexesMap { + fieldIndexes[id] = index + } m.fieldIndexLock.RUnlock() indexes, ok := m.segmentIndexes.Get(segmentID) @@ -551,11 +556,16 @@ func (m *indexMeta) GetSegmentIndexState(collID, segmentID UniqueID, indexID Uni func (m *indexMeta) GetIndexedSegments(collectionID int64, segmentIDs, fieldIDs []UniqueID) []int64 { m.fieldIndexLock.RLock() - fieldIndexes, ok := m.indexes[collectionID] + fieldIndexesMap, ok := m.indexes[collectionID] if !ok { m.fieldIndexLock.RUnlock() return nil } + // Copy the map to avoid data race after releasing the lock + fieldIndexes := make(map[UniqueID]*model.Index, len(fieldIndexesMap)) + for id, index := range fieldIndexesMap { + fieldIndexes[id] = index + } m.fieldIndexLock.RUnlock() fieldIDSet := typeutil.NewUniqueSet(fieldIDs...) @@ -684,11 +694,16 @@ func (m *indexMeta) MarkIndexAsDeleted(ctx context.Context, collID UniqueID, ind func (m *indexMeta) IsUnIndexedSegment(collectionID UniqueID, segID UniqueID) bool { m.fieldIndexLock.RLock() - fieldIndexes, ok := m.indexes[collectionID] + fieldIndexesMap, ok := m.indexes[collectionID] if !ok { m.fieldIndexLock.RUnlock() return false } + // Copy the map to avoid data race after releasing the lock + fieldIndexes := make(map[UniqueID]*model.Index, len(fieldIndexesMap)) + for id, index := range fieldIndexesMap { + fieldIndexes[id] = index + } m.fieldIndexLock.RUnlock() // the segment should be unindexed status if the fieldIndexes is not nil @@ -1189,12 +1204,17 @@ func (m *indexMeta) GetIndexJSON(collectionID int64) string { func (m *indexMeta) GetSegmentIndexedFields(collectionID UniqueID, segmentID UniqueID) (bool, []*metricsinfo.IndexedField) { m.fieldIndexLock.RLock() - fieldIndexes, ok := m.indexes[collectionID] + fieldIndexesMap, ok := m.indexes[collectionID] if !ok { // the segment should be unindexed status if the collection has no indexes m.fieldIndexLock.RUnlock() return false, []*metricsinfo.IndexedField{} } + // Copy the map to avoid data race after releasing the lock + fieldIndexes := make(map[UniqueID]*model.Index, len(fieldIndexesMap)) + for id, index := range fieldIndexesMap { + fieldIndexes[id] = index + } m.fieldIndexLock.RUnlock() // the segment should be unindexed status if the segment indexes is not found