2023-02-22 11:37:45 +08:00
// 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.
2022-09-05 13:29:11 +08:00
package rootcoord
import (
"context"
"fmt"
2023-02-26 11:31:49 +08:00
"github.com/cockroachdb/errors"
2023-01-11 14:35:40 +08:00
"go.uber.org/zap"
2022-09-05 13:29:11 +08:00
2023-06-09 01:28:37 +08:00
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
2023-01-11 14:35:40 +08:00
"github.com/milvus-io/milvus/internal/metastore/model"
"github.com/milvus-io/milvus/internal/proto/datapb"
"github.com/milvus-io/milvus/internal/proto/indexpb"
2022-09-05 13:29:11 +08:00
"github.com/milvus-io/milvus/internal/proto/querypb"
2023-04-06 19:14:32 +08:00
"github.com/milvus-io/milvus/pkg/log"
"github.com/milvus-io/milvus/pkg/util/commonpbutil"
2023-10-07 11:29:32 +08:00
"github.com/milvus-io/milvus/pkg/util/merr"
2023-04-06 19:14:32 +08:00
"github.com/milvus-io/milvus/pkg/util/typeutil"
2022-09-05 13:29:11 +08:00
)
type watchInfo struct {
ts Timestamp
collectionID UniqueID
partitionID UniqueID
vChannels [ ] string
startPositions [ ] * commonpb . KeyDataPair
2022-10-10 01:37:21 +08:00
schema * schemapb . CollectionSchema
2022-09-05 13:29:11 +08:00
}
// Broker communicates with other components.
type Broker interface {
ReleaseCollection ( ctx context . Context , collectionID UniqueID ) error
2023-03-20 14:55:57 +08:00
ReleasePartitions ( ctx context . Context , collectionID UniqueID , partitionIDs ... UniqueID ) error
SyncNewCreatedPartition ( ctx context . Context , collectionID UniqueID , partitionID UniqueID ) error
2022-09-05 13:29:11 +08:00
GetQuerySegmentInfo ( ctx context . Context , collectionID int64 , segIDs [ ] int64 ) ( retResp * querypb . GetSegmentInfoResponse , retErr error )
WatchChannels ( ctx context . Context , info * watchInfo ) error
UnwatchChannels ( ctx context . Context , info * watchInfo ) error
Flush ( ctx context . Context , cID int64 , segIDs [ ] int64 ) error
Import ( ctx context . Context , req * datapb . ImportTaskRequest ) ( * datapb . ImportTaskResponse , error )
2022-09-26 18:06:54 +08:00
UnsetIsImportingState ( context . Context , * datapb . UnsetIsImportingStateRequest ) ( * commonpb . Status , error )
2022-12-28 11:11:30 +08:00
GetSegmentStates ( context . Context , * datapb . GetSegmentStatesRequest ) ( * datapb . GetSegmentStatesResponse , error )
2023-01-12 09:55:42 +08:00
GcConfirm ( ctx context . Context , collectionID , partitionID UniqueID ) bool
2022-09-05 13:29:11 +08:00
2022-09-23 09:36:51 +08:00
DropCollectionIndex ( ctx context . Context , collID UniqueID , partIDs [ ] UniqueID ) error
2023-01-11 14:35:40 +08:00
GetSegmentIndexState ( ctx context . Context , collID UniqueID , indexName string , segIDs [ ] UniqueID ) ( [ ] * indexpb . SegmentIndexState , error )
DescribeIndex ( ctx context . Context , colID UniqueID ) ( * indexpb . DescribeIndexResponse , error )
2022-10-10 20:31:22 +08:00
2022-10-11 21:07:23 +08:00
BroadcastAlteredCollection ( ctx context . Context , req * milvuspb . AlterCollectionRequest ) error
2022-09-05 13:29:11 +08:00
}
type ServerBroker struct {
s * Core
}
func newServerBroker ( s * Core ) * ServerBroker {
return & ServerBroker { s : s }
}
func ( b * ServerBroker ) ReleaseCollection ( ctx context . Context , collectionID UniqueID ) error {
2023-04-17 11:00:30 +08:00
log . Ctx ( ctx ) . Info ( "releasing collection" , zap . Int64 ( "collection" , collectionID ) )
2022-09-05 13:29:11 +08:00
resp , err := b . s . queryCoord . ReleaseCollection ( ctx , & querypb . ReleaseCollectionRequest {
2022-10-21 15:57:28 +08:00
Base : commonpbutil . NewMsgBase ( commonpbutil . WithMsgType ( commonpb . MsgType_ReleaseCollection ) ) ,
2022-09-05 13:29:11 +08:00
CollectionID : collectionID ,
NodeID : b . s . session . ServerID ,
} )
if err != nil {
return err
}
if resp . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( "failed to release collection, code: %s, reason: %s" , resp . GetErrorCode ( ) , resp . GetReason ( ) )
}
2023-04-17 11:00:30 +08:00
log . Ctx ( ctx ) . Info ( "done to release collection" , zap . Int64 ( "collection" , collectionID ) )
2022-09-05 13:29:11 +08:00
return nil
}
2023-03-20 14:55:57 +08:00
func ( b * ServerBroker ) ReleasePartitions ( ctx context . Context , collectionID UniqueID , partitionIDs ... UniqueID ) error {
if len ( partitionIDs ) == 0 {
return nil
}
log := log . Ctx ( ctx ) . With ( zap . Int64 ( "collection" , collectionID ) , zap . Int64s ( "partitionIDs" , partitionIDs ) )
log . Info ( "releasing partitions" )
resp , err := b . s . queryCoord . ReleasePartitions ( ctx , & querypb . ReleasePartitionsRequest {
Base : commonpbutil . NewMsgBase ( commonpbutil . WithMsgType ( commonpb . MsgType_ReleasePartitions ) ) ,
CollectionID : collectionID ,
PartitionIDs : partitionIDs ,
} )
if err != nil {
return err
}
if resp . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( "release partition failed, reason: %s" , resp . GetReason ( ) )
}
log . Info ( "release partitions done" )
return nil
}
func ( b * ServerBroker ) SyncNewCreatedPartition ( ctx context . Context , collectionID UniqueID , partitionID UniqueID ) error {
log := log . Ctx ( ctx ) . With ( zap . Int64 ( "collection" , collectionID ) , zap . Int64 ( "partitionID" , partitionID ) )
log . Info ( "begin to sync new partition" )
resp , err := b . s . queryCoord . SyncNewCreatedPartition ( ctx , & querypb . SyncNewCreatedPartitionRequest {
Base : commonpbutil . NewMsgBase ( commonpbutil . WithMsgType ( commonpb . MsgType_ReleasePartitions ) ) ,
CollectionID : collectionID ,
PartitionID : partitionID ,
} )
if err != nil {
return err
}
if resp . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( "sync new partition failed, reason: %s" , resp . GetReason ( ) )
}
log . Info ( "sync new partition done" )
return nil
}
2022-09-05 13:29:11 +08:00
func ( b * ServerBroker ) GetQuerySegmentInfo ( ctx context . Context , collectionID int64 , segIDs [ ] int64 ) ( retResp * querypb . GetSegmentInfoResponse , retErr error ) {
resp , err := b . s . queryCoord . GetSegmentInfo ( ctx , & querypb . GetSegmentInfoRequest {
2022-10-21 15:57:28 +08:00
Base : commonpbutil . NewMsgBase (
commonpbutil . WithMsgType ( commonpb . MsgType_GetSegmentState ) ,
commonpbutil . WithSourceID ( b . s . session . ServerID ) ,
) ,
2022-09-05 13:29:11 +08:00
CollectionID : collectionID ,
SegmentIDs : segIDs ,
} )
return resp , err
}
func toKeyDataPairs ( m map [ string ] [ ] byte ) [ ] * commonpb . KeyDataPair {
ret := make ( [ ] * commonpb . KeyDataPair , 0 , len ( m ) )
for k , data := range m {
ret = append ( ret , & commonpb . KeyDataPair {
Key : k ,
Data : data ,
} )
}
return ret
}
func ( b * ServerBroker ) WatchChannels ( ctx context . Context , info * watchInfo ) error {
2023-04-17 11:00:30 +08:00
log . Ctx ( ctx ) . Info ( "watching channels" , zap . Uint64 ( "ts" , info . ts ) , zap . Int64 ( "collection" , info . collectionID ) , zap . Strings ( "vChannels" , info . vChannels ) )
2022-09-05 13:29:11 +08:00
resp , err := b . s . dataCoord . WatchChannels ( ctx , & datapb . WatchChannelsRequest {
2023-08-16 09:05:32 +08:00
CollectionID : info . collectionID ,
ChannelNames : info . vChannels ,
StartPositions : info . startPositions ,
Schema : info . schema ,
CreateTimestamp : info . ts ,
2022-09-05 13:29:11 +08:00
} )
if err != nil {
return err
}
if resp . GetStatus ( ) . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( "failed to watch channels, code: %s, reason: %s" , resp . GetStatus ( ) . GetErrorCode ( ) , resp . GetStatus ( ) . GetReason ( ) )
}
2023-04-17 11:00:30 +08:00
log . Ctx ( ctx ) . Info ( "done to watch channels" , zap . Uint64 ( "ts" , info . ts ) , zap . Int64 ( "collection" , info . collectionID ) , zap . Strings ( "vChannels" , info . vChannels ) )
2022-09-05 13:29:11 +08:00
return nil
}
func ( b * ServerBroker ) UnwatchChannels ( ctx context . Context , info * watchInfo ) error {
// TODO: release flowgraph on datanodes.
return nil
}
func ( b * ServerBroker ) Flush ( ctx context . Context , cID int64 , segIDs [ ] int64 ) error {
resp , err := b . s . dataCoord . Flush ( ctx , & datapb . FlushRequest {
2022-10-21 15:57:28 +08:00
Base : commonpbutil . NewMsgBase (
commonpbutil . WithMsgType ( commonpb . MsgType_Flush ) ,
commonpbutil . WithSourceID ( b . s . session . ServerID ) ,
) ,
2022-09-05 13:29:11 +08:00
DbID : 0 ,
SegmentIDs : segIDs ,
CollectionID : cID ,
2023-01-31 12:41:53 +08:00
IsImport : true ,
2022-09-05 13:29:11 +08:00
} )
if err != nil {
return errors . New ( "failed to call flush to data coordinator: " + err . Error ( ) )
}
2022-09-26 18:06:54 +08:00
if resp . GetStatus ( ) . GetErrorCode ( ) != commonpb . ErrorCode_Success {
2023-10-07 11:29:32 +08:00
return merr . Error ( resp . GetStatus ( ) )
2022-09-05 13:29:11 +08:00
}
2023-07-14 15:56:31 +08:00
log . Info ( "flush on collection succeed" , zap . Int64 ( "collectionID" , cID ) )
2022-09-05 13:29:11 +08:00
return nil
}
func ( b * ServerBroker ) Import ( ctx context . Context , req * datapb . ImportTaskRequest ) ( * datapb . ImportTaskResponse , error ) {
return b . s . dataCoord . Import ( ctx , req )
}
2022-09-26 18:06:54 +08:00
func ( b * ServerBroker ) UnsetIsImportingState ( ctx context . Context , req * datapb . UnsetIsImportingStateRequest ) ( * commonpb . Status , error ) {
return b . s . dataCoord . UnsetIsImportingState ( ctx , req )
}
2022-12-28 11:11:30 +08:00
func ( b * ServerBroker ) GetSegmentStates ( ctx context . Context , req * datapb . GetSegmentStatesRequest ) ( * datapb . GetSegmentStatesResponse , error ) {
return b . s . dataCoord . GetSegmentStates ( ctx , req )
}
2022-09-23 09:36:51 +08:00
func ( b * ServerBroker ) DropCollectionIndex ( ctx context . Context , collID UniqueID , partIDs [ ] UniqueID ) error {
2023-04-17 11:00:30 +08:00
log . Ctx ( ctx ) . Info ( "dropping collection index" , zap . Int64 ( "collection" , collID ) , zap . Int64s ( "partitions" , partIDs ) )
2023-01-11 14:35:40 +08:00
rsp , err := b . s . dataCoord . DropIndex ( ctx , & indexpb . DropIndexRequest {
2022-09-05 13:29:11 +08:00
CollectionID : collID ,
2022-09-23 09:36:51 +08:00
PartitionIDs : partIDs ,
2022-09-05 13:29:11 +08:00
IndexName : "" ,
2022-10-31 11:39:33 +08:00
DropAll : true ,
2022-09-05 13:29:11 +08:00
} )
if err != nil {
return err
}
if rsp . ErrorCode != commonpb . ErrorCode_Success {
return fmt . Errorf ( rsp . Reason )
}
2023-04-17 11:00:30 +08:00
log . Ctx ( ctx ) . Info ( "done to drop collection index" , zap . Int64 ( "collection" , collID ) , zap . Int64s ( "partitions" , partIDs ) )
2022-09-05 13:29:11 +08:00
return nil
}
2023-01-11 14:35:40 +08:00
func ( b * ServerBroker ) GetSegmentIndexState ( ctx context . Context , collID UniqueID , indexName string , segIDs [ ] UniqueID ) ( [ ] * indexpb . SegmentIndexState , error ) {
resp , err := b . s . dataCoord . GetSegmentIndexState ( ctx , & indexpb . GetSegmentIndexStateRequest {
2022-09-05 13:29:11 +08:00
CollectionID : collID ,
IndexName : indexName ,
SegmentIDs : segIDs ,
} )
if err != nil {
return nil , err
}
2023-09-12 16:07:18 +08:00
if resp . GetStatus ( ) . GetErrorCode ( ) != commonpb . ErrorCode_Success {
2023-10-07 11:29:32 +08:00
return nil , merr . Error ( resp . GetStatus ( ) )
2022-09-05 13:29:11 +08:00
}
return resp . GetStates ( ) , nil
}
2022-09-26 18:06:54 +08:00
2022-10-11 21:07:23 +08:00
func ( b * ServerBroker ) BroadcastAlteredCollection ( ctx context . Context , req * milvuspb . AlterCollectionRequest ) error {
2023-07-14 15:56:31 +08:00
log . Info ( "broadcasting request to alter collection" , zap . String ( "collectionName" , req . GetCollectionName ( ) ) , zap . Int64 ( "collectionID" , req . GetCollectionID ( ) ) )
2022-11-21 10:09:10 +08:00
2023-06-25 17:20:43 +08:00
colMeta , err := b . s . meta . GetCollectionByID ( ctx , req . GetDbName ( ) , req . GetCollectionID ( ) , typeutil . MaxTimestamp , false )
2022-11-21 10:09:10 +08:00
if err != nil {
return err
}
partitionIDs := make ( [ ] int64 , len ( colMeta . Partitions ) )
for _ , p := range colMeta . Partitions {
partitionIDs = append ( partitionIDs , p . PartitionID )
}
dcReq := & datapb . AlterCollectionRequest {
CollectionID : req . GetCollectionID ( ) ,
Schema : & schemapb . CollectionSchema {
Name : colMeta . Name ,
Description : colMeta . Description ,
AutoID : colMeta . AutoID ,
Fields : model . MarshalFieldModels ( colMeta . Fields ) ,
} ,
PartitionIDs : partitionIDs ,
StartPositions : colMeta . StartPositions ,
Properties : req . GetProperties ( ) ,
}
resp , err := b . s . dataCoord . BroadcastAlteredCollection ( ctx , dcReq )
2022-10-10 20:31:22 +08:00
if err != nil {
return err
}
if resp . ErrorCode != commonpb . ErrorCode_Success {
return errors . New ( resp . Reason )
}
2023-07-14 15:56:31 +08:00
log . Info ( "done to broadcast request to alter collection" , zap . String ( "collectionName" , req . GetCollectionName ( ) ) , zap . Int64 ( "collectionID" , req . GetCollectionID ( ) ) )
2022-10-10 20:31:22 +08:00
return nil
}
2023-01-11 14:35:40 +08:00
func ( b * ServerBroker ) DescribeIndex ( ctx context . Context , colID UniqueID ) ( * indexpb . DescribeIndexResponse , error ) {
return b . s . dataCoord . DescribeIndex ( ctx , & indexpb . DescribeIndexRequest {
2022-09-26 18:06:54 +08:00
CollectionID : colID ,
} )
}
2023-01-12 09:55:42 +08:00
func ( b * ServerBroker ) GcConfirm ( ctx context . Context , collectionID , partitionID UniqueID ) bool {
2023-06-19 10:52:41 +08:00
log := log . Ctx ( ctx ) . With ( zap . Int64 ( "collection" , collectionID ) , zap . Int64 ( "partition" , partitionID ) )
log . Info ( "confirming if gc is finished" )
2023-01-12 09:55:42 +08:00
req := & datapb . GcConfirmRequest { CollectionId : collectionID , PartitionId : partitionID }
resp , err := b . s . dataCoord . GcConfirm ( ctx , req )
if err != nil {
2023-06-19 10:52:41 +08:00
log . Warn ( "gc is not finished" , zap . Error ( err ) )
2023-01-12 09:55:42 +08:00
return false
}
2023-06-19 10:52:41 +08:00
2023-01-12 09:55:42 +08:00
if resp . GetStatus ( ) . GetErrorCode ( ) != commonpb . ErrorCode_Success {
2023-06-19 10:52:41 +08:00
log . Warn ( "gc is not finished" , zap . String ( "code" , resp . GetStatus ( ) . GetErrorCode ( ) . String ( ) ) ,
zap . String ( "reason" , resp . GetStatus ( ) . GetReason ( ) ) )
2023-01-12 09:55:42 +08:00
return false
}
2023-06-19 10:52:41 +08:00
log . Info ( "received gc_confirm response" , zap . Bool ( "finished" , resp . GetGcFinished ( ) ) )
2023-01-12 09:55:42 +08:00
return resp . GetGcFinished ( )
}