mirror of
https://github.com/milvus-io/milvus.git
synced 2026-07-21 10:15:43 +00:00
issue: #49991 See also: #49991 Target-size manual compaction should use the same candidate rules as normal manual compaction. Share the candidate predicate so force merge only plans healthy, flushed, visible, sorted, non-L0, non-L2 segments and skips compacting, importing, or snapshot-protected segments. Signed-off-by: yangxuan <xuan.yang@zilliz.com> Signed-off-by: yangxuan <xuan.yang@zilliz.com>
144 lines
5.1 KiB
Go
144 lines
5.1 KiB
Go
// Licensed to the LF AI & Data foundation under one
|
|
// or more contributor license agreements. See the NOTICE file
|
|
// distributed with this work for additional information
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
// to you under the Apache License, Version 2.0 (the
|
|
// "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package datacoord
|
|
|
|
import (
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
"github.com/milvus-io/milvus-proto/go-api/v3/commonpb"
|
|
"github.com/milvus-io/milvus-proto/go-api/v3/schemapb"
|
|
"github.com/milvus-io/milvus/internal/datacoord/allocator"
|
|
"github.com/milvus-io/milvus/internal/util/hookutil"
|
|
"github.com/milvus-io/milvus/internal/util/importutilv2"
|
|
"github.com/milvus-io/milvus/pkg/v3/proto/datapb"
|
|
"github.com/milvus-io/milvus/pkg/v3/proto/workerpb"
|
|
"github.com/milvus-io/milvus/pkg/v3/util/paramtable"
|
|
)
|
|
|
|
// PreAllocateBinlogIDs pre-allocates binlog IDs based on the total number of binlogs from
|
|
// the segments for compaction, multiplied by an expansion factor.
|
|
// The schema is used to calculate a minimum ID count for V3 manifest segments where
|
|
// binlog metadata may be empty but stats output still requires IDs.
|
|
func PreAllocateBinlogIDs(allocator allocator.Allocator, segmentInfos []*SegmentInfo, schema *schemapb.CollectionSchema) (*datapb.IDRange, error) {
|
|
binlogNum := 0
|
|
for _, s := range segmentInfos {
|
|
for _, l := range s.GetBinlogs() {
|
|
binlogNum += len(l.GetBinlogs())
|
|
}
|
|
for _, l := range s.GetDeltalogs() {
|
|
binlogNum += len(l.GetBinlogs())
|
|
}
|
|
for _, l := range s.GetStatslogs() {
|
|
binlogNum += len(l.GetBinlogs())
|
|
}
|
|
for _, l := range s.GetBm25Statslogs() {
|
|
binlogNum += len(l.GetBinlogs())
|
|
}
|
|
}
|
|
// Compaction output always needs IDs for PK stats (1) and BM25 stats (per BM25 function).
|
|
// For V3 manifest segments, binlog metadata may be empty since data is managed by manifest,
|
|
// but stats output still requires IDs. Calculate the minimum from schema directly.
|
|
minIDsFromSchema := 1 // 1 for PK stats
|
|
if schema != nil {
|
|
for _, fn := range schema.GetFunctions() {
|
|
if fn.GetType() == schemapb.FunctionType_BM25 {
|
|
minIDsFromSchema++
|
|
}
|
|
}
|
|
}
|
|
if binlogNum < minIDsFromSchema {
|
|
binlogNum = minIDsFromSchema
|
|
}
|
|
n := binlogNum * paramtable.Get().DataCoordCfg.CompactionPreAllocateIDExpansionFactor.GetAsInt()
|
|
begin, end, err := allocator.AllocN(int64(n))
|
|
return &datapb.IDRange{Begin: begin, End: end}, err
|
|
}
|
|
|
|
// Return None nil slice
|
|
func GetReadPluginContext(options importutilv2.Options) []*commonpb.KeyValuePair {
|
|
importEzk, _ := importutilv2.GetEZK(options)
|
|
return hookutil.GetReadStoragePluginContext(importEzk)
|
|
}
|
|
|
|
func WrapPluginContext(collectionID int64, properties []*commonpb.KeyValuePair, msg proto.Message) {
|
|
pluginContext := hookutil.GetStoragePluginContext(properties, collectionID)
|
|
if pluginContext == nil {
|
|
return
|
|
}
|
|
|
|
switch msg := msg.(type) {
|
|
case *datapb.CompactionPlan:
|
|
plan := msg
|
|
plan.PluginContext = append(plan.PluginContext, pluginContext...)
|
|
case *workerpb.CreateJobRequest:
|
|
job := msg
|
|
job.PluginContext = append(job.PluginContext, pluginContext...)
|
|
case *workerpb.AnalyzeRequest:
|
|
job := msg
|
|
job.PluginContext = append(job.PluginContext, pluginContext...)
|
|
case *workerpb.CreateStatsRequest:
|
|
job := msg
|
|
job.PluginContext = append(job.PluginContext, pluginContext...)
|
|
case *datapb.ImportRequest:
|
|
job := msg
|
|
job.PluginContext = append(job.PluginContext, pluginContext...)
|
|
case *datapb.PreImportRequest:
|
|
job := msg
|
|
job.PluginContext = append(job.PluginContext, pluginContext...)
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
|
|
func isNormalManualCompactionCandidate(meta *meta, segment *SegmentInfo) bool {
|
|
return isSegmentHealthy(segment) &&
|
|
isFlushed(segment) &&
|
|
!segment.isCompacting &&
|
|
!segment.GetIsImporting() &&
|
|
segment.GetLevel() != datapb.SegmentLevel_L0 &&
|
|
segment.GetLevel() != datapb.SegmentLevel_L2 &&
|
|
!segment.GetIsInvisible() &&
|
|
(segment.GetIsSorted() || segment.GetIsSortedByNamespace()) &&
|
|
!meta.isSegmentCompactionProtected(segment.GetID())
|
|
}
|
|
|
|
// isCompactionTaskFinished returns true if the task has reached a terminal state
|
|
// (timeout, completed, cleaned, or unknown) and requires no further processing.
|
|
func isCompactionTaskFinished(t *datapb.CompactionTask) bool {
|
|
switch t.GetState() {
|
|
case datapb.CompactionTaskState_timeout,
|
|
datapb.CompactionTaskState_completed,
|
|
datapb.CompactionTaskState_cleaned,
|
|
datapb.CompactionTaskState_unknown:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// isCompactionTaskCleaned returns true if the task has been cleaned
|
|
// (cleaned, or unknown) and requires no further processing.
|
|
func isCompactionTaskCleaned(t *datapb.CompactionTask) bool {
|
|
switch t.GetState() {
|
|
case datapb.CompactionTaskState_cleaned,
|
|
datapb.CompactionTaskState_unknown:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|