2021-12-20 09:45:37 +00: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
2021-04-19 03:12:56 +00:00
// with the License. You may obtain a copy of the License at
//
2021-12-20 09:45:37 +00:00
// http://www.apache.org/licenses/LICENSE-2.0
2021-04-19 03:12:56 +00:00
//
2021-12-20 09:45:37 +00:00
// 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.
2021-04-19 03:12:56 +00:00
2021-06-18 13:30:08 +00:00
package rootcoord
2021-01-19 06:44:03 +00:00
import (
"context"
2022-04-25 03:07:47 +00:00
"errors"
2021-01-25 10:33:10 +00:00
"fmt"
2021-01-19 06:44:03 +00:00
"math/rand"
2022-03-17 09:17:22 +00:00
"os"
2021-08-18 06:36:10 +00:00
"strconv"
2021-01-19 06:44:03 +00:00
"sync"
"sync/atomic"
2021-11-22 08:23:17 +00:00
"syscall"
2021-01-19 06:44:03 +00:00
"time"
2021-04-22 06:45:57 +00:00
"github.com/milvus-io/milvus/internal/allocator"
2021-12-17 06:13:16 +00:00
"github.com/milvus-io/milvus/internal/common"
2021-10-01 03:08:24 +00:00
"github.com/milvus-io/milvus/internal/kv"
2021-04-22 06:45:57 +00:00
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
"github.com/milvus-io/milvus/internal/log"
2022-08-11 04:12:38 +00:00
"github.com/milvus-io/milvus/internal/metastore"
"github.com/milvus-io/milvus/internal/metastore/db/dao"
"github.com/milvus-io/milvus/internal/metastore/db/dbcore"
2022-08-20 02:24:51 +00:00
rootcoord2 "github.com/milvus-io/milvus/internal/metastore/db/rootcoord"
"github.com/milvus-io/milvus/internal/metastore/kv/rootcoord"
2022-07-22 02:20:29 +00:00
"github.com/milvus-io/milvus/internal/metastore/model"
2021-06-01 03:04:31 +00:00
"github.com/milvus-io/milvus/internal/metrics"
2022-03-03 13:57:56 +00:00
ms "github.com/milvus-io/milvus/internal/mq/msgstream"
2021-04-22 06:45:57 +00:00
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/datapb"
"github.com/milvus-io/milvus/internal/proto/indexpb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
"github.com/milvus-io/milvus/internal/proto/milvuspb"
"github.com/milvus-io/milvus/internal/proto/proxypb"
"github.com/milvus-io/milvus/internal/proto/querypb"
2021-06-22 08:14:09 +00:00
"github.com/milvus-io/milvus/internal/proto/rootcoordpb"
2021-04-22 06:45:57 +00:00
"github.com/milvus-io/milvus/internal/tso"
"github.com/milvus-io/milvus/internal/types"
2022-04-21 11:57:42 +00:00
"github.com/milvus-io/milvus/internal/util"
"github.com/milvus-io/milvus/internal/util/crypto"
"github.com/milvus-io/milvus/internal/util/dependency"
2022-08-11 04:12:38 +00:00
"github.com/milvus-io/milvus/internal/util/errorutil"
"github.com/milvus-io/milvus/internal/util/funcutil"
2021-10-01 03:08:24 +00:00
"github.com/milvus-io/milvus/internal/util/metricsinfo"
2021-12-23 10:39:11 +00:00
"github.com/milvus-io/milvus/internal/util/paramtable"
2021-04-22 06:45:57 +00:00
"github.com/milvus-io/milvus/internal/util/retry"
2021-05-21 11:28:52 +00:00
"github.com/milvus-io/milvus/internal/util/sessionutil"
2022-03-28 08:41:28 +00:00
"github.com/milvus-io/milvus/internal/util/timerecord"
2021-06-30 08:18:13 +00:00
"github.com/milvus-io/milvus/internal/util/trace"
2021-04-22 06:45:57 +00:00
"github.com/milvus-io/milvus/internal/util/tsoutil"
"github.com/milvus-io/milvus/internal/util/typeutil"
2022-07-22 02:20:29 +00:00
clientv3 "go.etcd.io/etcd/client/v3"
"go.uber.org/zap"
2021-01-19 06:44:03 +00:00
)
2022-03-28 08:41:28 +00:00
// UniqueID is an alias of typeutil.UniqueID.
type UniqueID = typeutil . UniqueID
2022-05-19 02:13:56 +00:00
const InvalidCollectionID = UniqueID ( 0 )
2021-01-19 06:44:03 +00:00
// ------------------ struct -----------------------
2021-12-23 06:34:13 +00:00
// DdOperation used to save ddMsg into etcd
2021-05-14 13:26:06 +00:00
type DdOperation struct {
2021-09-23 02:37:54 +00:00
Body [ ] byte ` json:"body" `
2021-07-06 01:16:03 +00:00
Type string ` json:"type" `
2021-05-14 13:26:06 +00:00
}
2021-06-22 11:08:03 +00:00
func metricProxy ( v int64 ) string {
2021-06-01 03:04:31 +00:00
return fmt . Sprintf ( "client_%d" , v )
}
2022-04-03 03:37:29 +00:00
var Params paramtable . ComponentParam
2021-12-23 10:39:11 +00:00
2021-06-17 08:47:57 +00:00
// Core root coordinator core
2021-01-19 06:44:03 +00:00
type Core struct {
2021-09-23 07:10:00 +00:00
MetaTable * MetaTable
2021-01-19 06:44:03 +00:00
//id allocator
2021-05-20 06:14:14 +00:00
IDAllocator func ( count uint32 ) ( typeutil . UniqueID , typeutil . UniqueID , error )
IDAllocatorUpdate func ( ) error
2021-04-08 09:31:39 +00:00
2021-01-19 06:44:03 +00:00
//tso allocator
2022-03-02 13:11:57 +00:00
TSOAllocator func ( count uint32 ) ( typeutil . Timestamp , error )
TSOAllocatorUpdate func ( ) error
TSOGetLastSavedTime func ( ) time . Time
2021-01-19 06:44:03 +00:00
//inner members
2022-03-25 03:03:25 +00:00
ctx context . Context
cancel context . CancelFunc
wg sync . WaitGroup
etcdCli * clientv3 . Client
kvBase kv . TxnKV //*etcdkv.EtcdKV
impTaskKv kv . MetaKv
2021-01-19 06:44:03 +00:00
2021-08-18 06:36:10 +00:00
//DDL lock
ddlLock sync . Mutex
2021-09-15 14:05:49 +00:00
kvBaseCreate func ( root string ) ( kv . TxnKV , error )
2022-03-25 03:03:25 +00:00
metaKVCreate func ( root string ) ( kv . MetaKv , error )
2021-01-20 01:36:50 +00:00
//setMsgStreams, send time tick into dd channel and time tick channel
2021-08-18 06:36:10 +00:00
SendTimeTick func ( t typeutil . Timestamp , reason string ) error
2021-01-19 06:44:03 +00:00
2021-01-20 01:36:50 +00:00
//setMsgStreams, send create collection into dd channel
2021-09-27 10:10:00 +00:00
//returns corresponding message id for each channel
SendDdCreateCollectionReq func ( ctx context . Context , req * internalpb . CreateCollectionRequest , channelNames [ ] string ) ( map [ string ] [ ] byte , error )
2021-01-19 06:44:03 +00:00
2021-01-20 01:36:50 +00:00
//setMsgStreams, send drop collection into dd channel, and notify the proxy to delete this collection
2021-06-11 08:39:29 +00:00
SendDdDropCollectionReq func ( ctx context . Context , req * internalpb . DropCollectionRequest , channelNames [ ] string ) error
2021-01-19 06:44:03 +00:00
2021-01-20 01:36:50 +00:00
//setMsgStreams, send create partition into dd channel
2021-06-11 08:39:29 +00:00
SendDdCreatePartitionReq func ( ctx context . Context , req * internalpb . CreatePartitionRequest , channelNames [ ] string ) error
2021-01-19 06:44:03 +00:00
2021-01-20 01:36:50 +00:00
//setMsgStreams, send drop partition into dd channel
2021-06-11 08:39:29 +00:00
SendDdDropPartitionReq func ( ctx context . Context , req * internalpb . DropPartitionRequest , channelNames [ ] string ) error
2021-01-19 06:44:03 +00:00
2022-05-31 08:36:03 +00:00
//get segment info from data service
2021-07-03 06:36:18 +00:00
CallGetFlushedSegmentsService func ( ctx context . Context , collID , partID typeutil . UniqueID ) ( [ ] typeutil . UniqueID , error )
2022-05-31 08:36:03 +00:00
CallGetRecoveryInfoService func ( ctx context . Context , collID , partID UniqueID ) ( [ ] * datapb . SegmentBinlogs , error )
2021-01-21 02:01:29 +00:00
2022-03-28 08:41:28 +00:00
//call index builder's client to build index, return build id or get index state.
2022-07-22 02:20:29 +00:00
CallBuildIndexService func ( ctx context . Context , segID UniqueID , binlog [ ] string , field * model . Field , idxInfo * model . Index , numRows int64 ) ( typeutil . UniqueID , error )
2022-03-28 08:41:28 +00:00
CallDropIndexService func ( ctx context . Context , indexID typeutil . UniqueID ) error
2022-06-17 10:08:12 +00:00
CallRemoveIndexService func ( ctx context . Context , buildIDs [ ] UniqueID ) error
2022-03-28 08:41:28 +00:00
CallGetIndexStatesService func ( ctx context . Context , IndexBuildIDs [ ] int64 ) ( [ ] * indexpb . IndexInfo , error )
2021-01-21 02:01:29 +00:00
2021-06-22 11:08:03 +00:00
NewProxyClient func ( sess * sessionutil . Session ) ( types . Proxy , error )
2021-01-23 02:12:41 +00:00
2021-02-05 06:09:55 +00:00
//query service interface, notify query service to release collection
2021-06-22 08:08:08 +00:00
CallReleaseCollectionService func ( ctx context . Context , ts typeutil . Timestamp , dbID , collectionID typeutil . UniqueID ) error
CallReleasePartitionService func ( ctx context . Context , ts typeutil . Timestamp , dbID , collectionID typeutil . UniqueID , partitionIDs [ ] typeutil . UniqueID ) error
2021-02-05 06:09:55 +00:00
2022-05-05 13:17:50 +00:00
// Communicates with queryCoord service for segments info.
CallGetSegmentInfoService func ( ctx context . Context , collectionID int64 , segIDs [ ] int64 ) ( * querypb . GetSegmentInfoResponse , error )
2021-11-10 16:54:45 +00:00
2022-08-22 06:42:52 +00:00
CallWatchChannels func ( ctx context . Context , collectionID int64 , channelNames [ ] string , startPositions [ ] * commonpb . KeyDataPair ) error
2022-04-06 07:33:32 +00:00
2022-03-21 07:47:23 +00:00
//assign import task to data service
2022-04-01 03:33:28 +00:00
CallImportService func ( ctx context . Context , req * datapb . ImportTaskRequest ) * datapb . ImportTaskResponse
2022-03-21 07:47:23 +00:00
2022-04-25 03:07:47 +00:00
// Seals segments in collection cID, so they can get flushed later.
CallFlushOnCollection func ( ctx context . Context , cID int64 , segIDs [ ] int64 ) error
2022-06-15 04:20:10 +00:00
// CallAddSegRefLock triggers AcquireSegmentLock method on DataCoord.
2022-06-15 13:38:10 +00:00
CallAddSegRefLock func ( ctx context . Context , taskID int64 , segIDs [ ] int64 ) ( retErr error )
2022-06-15 04:20:10 +00:00
// CallReleaseSegRefLock triggers ReleaseSegmentLock method on DataCoord.
2022-06-15 13:38:10 +00:00
CallReleaseSegRefLock func ( ctx context . Context , taskID int64 , segIDs [ ] int64 ) ( retErr error )
2022-06-15 04:20:10 +00:00
2021-06-22 11:08:03 +00:00
//Proxy manager
proxyManager * proxyManager
2021-05-26 12:14:30 +00:00
// proxy clients
proxyClientManager * proxyClientManager
2021-09-03 09:15:26 +00:00
// metrics cache manager
metricsCacheManager * metricsinfo . MetricsCacheManager
2021-05-21 08:08:12 +00:00
// channel timetick
chanTimeTick * timetickSync
2021-01-19 06:44:03 +00:00
//time tick loop
lastTimeTick typeutil . Timestamp
//states code
stateCode atomic . Value
//call once
initOnce sync . Once
startOnce sync . Once
2021-02-23 03:40:30 +00:00
//isInit atomic.Value
2021-02-08 06:30:54 +00:00
2021-10-14 08:40:35 +00:00
session * sessionutil . Session
2021-05-21 11:28:52 +00:00
2022-04-07 14:05:32 +00:00
factory dependency . Factory
2022-03-21 07:47:23 +00:00
//import manager
importManager * importManager
2021-01-19 06:44:03 +00:00
}
// --------------------- function --------------------------
2021-12-28 11:47:21 +00:00
// NewCore creates a new rootcoord core
2022-04-07 14:05:32 +00:00
func NewCore ( c context . Context , factory dependency . Factory ) ( * Core , error ) {
2021-01-19 06:44:03 +00:00
ctx , cancel := context . WithCancel ( c )
rand . Seed ( time . Now ( ) . UnixNano ( ) )
core := & Core {
2022-04-07 14:05:32 +00:00
ctx : ctx ,
cancel : cancel ,
ddlLock : sync . Mutex { } ,
factory : factory ,
2021-01-19 06:44:03 +00:00
}
2021-03-12 06:22:09 +00:00
core . UpdateStateCode ( internalpb . StateCode_Abnormal )
2021-01-19 06:44:03 +00:00
return core , nil
}
2021-09-23 07:10:00 +00:00
// UpdateStateCode update state code
2021-03-12 06:22:09 +00:00
func ( c * Core ) UpdateStateCode ( code internalpb . StateCode ) {
2021-02-23 03:40:30 +00:00
c . stateCode . Store ( code )
}
2021-11-19 04:11:12 +00:00
func ( c * Core ) checkHealthy ( ) ( internalpb . StateCode , bool ) {
2021-08-31 03:45:59 +00:00
code := c . stateCode . Load ( ) . ( internalpb . StateCode )
2021-11-19 04:11:12 +00:00
ok := code == internalpb . StateCode_Healthy
return code , ok
}
func failStatus ( code commonpb . ErrorCode , reason string ) * commonpb . Status {
return & commonpb . Status {
ErrorCode : code ,
Reason : reason ,
}
}
func succStatus ( ) * commonpb . Status {
return & commonpb . Status {
ErrorCode : commonpb . ErrorCode_Success ,
Reason : "" ,
}
2021-08-31 03:45:59 +00:00
}
2021-01-19 06:44:03 +00:00
func ( c * Core ) checkInit ( ) error {
if c . MetaTable == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "metaTable is nil" )
2021-01-19 06:44:03 +00:00
}
2021-05-20 06:14:14 +00:00
if c . IDAllocator == nil {
2021-04-08 07:26:18 +00:00
return fmt . Errorf ( "idAllocator is nil" )
2021-01-19 06:44:03 +00:00
}
2021-05-20 06:14:14 +00:00
if c . IDAllocatorUpdate == nil {
2021-04-08 09:31:39 +00:00
return fmt . Errorf ( "idAllocatorUpdate is nil" )
}
2021-05-20 06:14:14 +00:00
if c . TSOAllocator == nil {
2021-04-08 07:26:18 +00:00
return fmt . Errorf ( "tsoAllocator is nil" )
2021-01-19 06:44:03 +00:00
}
2021-05-20 06:14:14 +00:00
if c . TSOAllocatorUpdate == nil {
2021-04-08 09:31:39 +00:00
return fmt . Errorf ( "tsoAllocatorUpdate is nil" )
}
2021-01-19 06:44:03 +00:00
if c . etcdCli == nil {
2021-04-08 07:26:18 +00:00
return fmt . Errorf ( "etcdCli is nil" )
2021-01-19 06:44:03 +00:00
}
if c . kvBase == nil {
2021-04-08 07:26:18 +00:00
return fmt . Errorf ( "kvBase is nil" )
2021-01-19 06:44:03 +00:00
}
2022-03-25 03:03:25 +00:00
if c . impTaskKv == nil {
return fmt . Errorf ( "impTaskKv is nil" )
}
2021-05-14 13:26:06 +00:00
if c . SendDdCreateCollectionReq == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "sendDdCreateCollectionReq is nil" )
2021-01-19 06:44:03 +00:00
}
2021-05-14 13:26:06 +00:00
if c . SendDdDropCollectionReq == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "sendDdDropCollectionReq is nil" )
2021-01-19 06:44:03 +00:00
}
2021-05-14 13:26:06 +00:00
if c . SendDdCreatePartitionReq == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "sendDdCreatePartitionReq is nil" )
2021-01-19 06:44:03 +00:00
}
2021-05-14 13:26:06 +00:00
if c . SendDdDropPartitionReq == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "sendDdDropPartitionReq is nil" )
2021-01-19 06:44:03 +00:00
}
2022-05-31 08:36:03 +00:00
if c . CallGetFlushedSegmentsService == nil {
return fmt . Errorf ( "callGetFlushedSegmentsService is nil" )
2021-01-21 02:01:29 +00:00
}
2022-05-31 08:36:03 +00:00
if c . CallGetRecoveryInfoService == nil {
return fmt . Errorf ( "CallGetRecoveryInfoService is nil" )
2021-03-08 07:46:51 +00:00
}
2021-05-25 06:03:06 +00:00
if c . CallBuildIndexService == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "callBuildIndexService is nil" )
2021-01-21 02:01:29 +00:00
}
2021-05-25 06:03:06 +00:00
if c . CallDropIndexService == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "callDropIndexService is nil" )
2021-02-20 07:38:44 +00:00
}
2022-06-17 10:08:12 +00:00
if c . CallRemoveIndexService == nil {
return fmt . Errorf ( "callDropIndexService is nil" )
}
2021-11-10 16:54:45 +00:00
if c . CallWatchChannels == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "callWatchChannels is nil" )
2021-11-10 16:54:45 +00:00
}
2021-05-26 12:14:30 +00:00
if c . NewProxyClient == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "newProxyClient is nil" )
2021-05-25 06:03:06 +00:00
}
if c . CallReleaseCollectionService == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "callReleaseCollectionService is nil" )
2021-01-23 02:12:41 +00:00
}
2021-06-22 08:08:08 +00:00
if c . CallReleasePartitionService == nil {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "callReleasePartitionService is nil" )
2021-06-22 08:08:08 +00:00
}
2022-03-21 07:47:23 +00:00
if c . CallImportService == nil {
return fmt . Errorf ( "callImportService is nil" )
}
2022-06-15 04:20:10 +00:00
if c . CallAddSegRefLock == nil {
return fmt . Errorf ( "callAddSegRefLock is nil" )
}
if c . CallReleaseSegRefLock == nil {
return fmt . Errorf ( "callReleaseSegRefLock is nil" )
}
2021-05-26 12:14:30 +00:00
2021-01-19 06:44:03 +00:00
return nil
}
func ( c * Core ) startTimeTickLoop ( ) {
2021-09-17 04:37:50 +00:00
defer c . wg . Done ( )
2021-12-27 13:38:45 +00:00
ticker := time . NewTicker ( Params . ProxyCfg . TimeTickInterval )
2021-05-31 08:48:31 +00:00
for {
select {
case <- c . ctx . Done ( ) :
2021-06-17 08:47:57 +00:00
log . Debug ( "rootcoord context closed" , zap . Error ( c . ctx . Err ( ) ) )
2021-05-31 08:48:31 +00:00
return
case <- ticker . C :
2021-08-18 06:36:10 +00:00
c . ddlLock . Lock ( )
2021-06-23 07:28:09 +00:00
if ts , err := c . TSOAllocator ( 1 ) ; err == nil {
2022-01-14 15:55:34 +00:00
err := c . SendTimeTick ( ts , "timetick loop" )
if err != nil {
log . Warn ( "Failed to send timetick" , zap . Error ( err ) )
}
2021-01-19 06:44:03 +00:00
}
2021-08-18 06:36:10 +00:00
c . ddlLock . Unlock ( )
2021-01-19 06:44:03 +00:00
}
}
}
2021-01-27 08:38:18 +00:00
func ( c * Core ) tsLoop ( ) {
2021-09-17 04:37:50 +00:00
defer c . wg . Done ( )
2021-02-24 09:12:06 +00:00
tsoTicker := time . NewTicker ( tso . UpdateTimestampStep )
2021-01-27 08:38:18 +00:00
defer tsoTicker . Stop ( )
ctx , cancel := context . WithCancel ( c . ctx )
defer cancel ( )
for {
select {
case <- tsoTicker . C :
2021-05-20 06:14:14 +00:00
if err := c . TSOAllocatorUpdate ( ) ; err != nil {
2021-03-15 07:45:17 +00:00
log . Warn ( "failed to update timestamp: " , zap . Error ( err ) )
continue
2021-01-27 08:38:18 +00:00
}
2022-03-02 13:11:57 +00:00
ts := c . TSOGetLastSavedTime ( )
2022-04-27 15:03:47 +00:00
metrics . RootCoordTimestampSaved . Set ( float64 ( ts . Unix ( ) ) )
2021-05-20 06:14:14 +00:00
if err := c . IDAllocatorUpdate ( ) ; err != nil {
2021-03-15 07:45:17 +00:00
log . Warn ( "failed to update id: " , zap . Error ( err ) )
continue
2021-01-27 08:38:18 +00:00
}
case <- ctx . Done ( ) :
// Server is closed and it should return nil.
2021-02-27 02:11:52 +00:00
log . Debug ( "tsLoop is closed" )
2021-01-27 08:38:18 +00:00
return
}
}
}
2021-05-14 13:26:06 +00:00
2021-07-03 09:54:25 +00:00
func ( c * Core ) checkFlushedSegmentsLoop ( ) {
2021-09-17 04:37:50 +00:00
defer c . wg . Done ( )
2021-07-03 09:54:25 +00:00
ticker := time . NewTicker ( 10 * time . Minute )
for {
select {
case <- c . ctx . Done ( ) :
2021-10-13 02:50:41 +00:00
log . Debug ( "RootCoord context done, exit check FlushedSegmentsLoop" )
2021-07-03 09:54:25 +00:00
return
case <- ticker . C :
log . Debug ( "check flushed segments" )
2021-08-25 06:41:52 +00:00
c . checkFlushedSegments ( c . ctx )
}
}
}
2022-06-17 10:08:12 +00:00
func ( c * Core ) recycleDroppedIndex ( ) {
defer c . wg . Done ( )
ticker := time . NewTicker ( 3 * time . Second )
for {
select {
case <- c . ctx . Done ( ) :
return
case <- ticker . C :
droppedIndex := c . MetaTable . GetDroppedIndex ( )
2022-07-22 02:20:29 +00:00
for collID , idxIDs := range droppedIndex {
for _ , indexID := range idxIDs {
2022-06-17 10:08:12 +00:00
if err := c . CallDropIndexService ( c . ctx , indexID ) ; err != nil {
2022-07-22 02:20:29 +00:00
log . Warn ( "Notify IndexCoord to drop index failed, wait to retry" ,
zap . Int64 ( "collID" , collID ) ,
zap . Int64 ( "indexID" , indexID ) )
2022-06-17 10:08:12 +00:00
}
}
}
err := c . MetaTable . RecycleDroppedIndex ( )
if err != nil {
log . Warn ( "Remove index meta failed, wait to retry" , zap . Error ( err ) )
}
}
}
}
func ( c * Core ) createIndexForSegment ( ctx context . Context , collID , partID , segID UniqueID , numRows int64 , binlogs [ ] * datapb . FieldBinlog ) error {
collID2Meta , _ , indexID2Meta := c . MetaTable . dupMeta ( )
collMeta , ok := collID2Meta [ collID ]
if ! ok {
log . Error ( "collection meta is not exist" , zap . Int64 ( "collID" , collID ) )
return fmt . Errorf ( "collection meta is not exist with ID = %d" , collID )
}
2022-07-22 02:20:29 +00:00
if len ( collMeta . FieldIDToIndexID ) == 0 {
2022-06-17 10:08:12 +00:00
log . Info ( "collection has no index, no need to build index on segment" , zap . Int64 ( "collID" , collID ) ,
zap . Int64 ( "segID" , segID ) )
return nil
}
2022-07-22 02:20:29 +00:00
for _ , t := range collMeta . FieldIDToIndexID {
fieldID := t . Key
indexID := t . Value
indexMeta , ok := indexID2Meta [ indexID ]
2022-06-17 10:08:12 +00:00
if ! ok {
2022-07-22 02:20:29 +00:00
log . Warn ( "index has no meta" , zap . Int64 ( "collID" , collID ) , zap . Int64 ( "indexID" , indexID ) )
return fmt . Errorf ( "index has no meta with ID = %d in collection %d" , indexID , collID )
2022-06-17 10:08:12 +00:00
}
2022-07-22 02:20:29 +00:00
if indexMeta . IsDeleted {
2022-06-17 10:08:12 +00:00
log . Info ( "index has been deleted, no need to build index on segment" )
continue
}
2022-07-22 02:20:29 +00:00
field , err := GetFieldSchemaByID ( & collMeta , fieldID )
2022-06-17 10:08:12 +00:00
if err != nil {
2022-06-21 10:44:12 +00:00
log . Error ( "GetFieldSchemaByID failed" ,
2022-06-17 10:08:12 +00:00
zap . Int64 ( "collectionID" , collID ) ,
2022-07-22 02:20:29 +00:00
zap . Int64 ( "fieldID" , fieldID ) )
2022-06-17 10:08:12 +00:00
return err
}
if c . MetaTable . IsSegmentIndexed ( segID , field , indexMeta . IndexParams ) {
continue
}
2022-06-21 10:44:12 +00:00
createTS , err := c . TSOAllocator ( 1 )
if err != nil {
log . Error ( "RootCoord alloc timestamp failed" , zap . Int64 ( "collectionID" , collID ) , zap . Error ( err ) )
return err
}
2022-06-17 10:08:12 +00:00
2022-07-22 02:20:29 +00:00
indexInfo := model . Index {
CollectionID : collMeta . CollectionID ,
FieldID : fieldID ,
IndexID : indexID ,
SegmentIndexes : map [ int64 ] model . SegmentIndex {
segID : {
Segment : model . Segment {
PartitionID : partID ,
SegmentID : segID ,
} ,
EnableIndex : false ,
CreateTime : createTS ,
} ,
} ,
2022-06-17 10:08:12 +00:00
}
2022-07-22 02:20:29 +00:00
segIndexInfo := indexInfo . SegmentIndexes [ segID ]
2022-06-17 10:08:12 +00:00
buildID , err := c . BuildIndex ( ctx , segID , numRows , binlogs , field , & indexMeta , false )
if err != nil {
log . Debug ( "build index failed" ,
zap . Int64 ( "segmentID" , segID ) ,
zap . Int64 ( "fieldID" , field . FieldID ) ,
zap . Int64 ( "indexID" , indexMeta . IndexID ) )
return err
}
// if buildID == 0, means it's no need to build index.
if buildID != 0 {
segIndexInfo . BuildID = buildID
segIndexInfo . EnableIndex = true
}
2022-07-22 02:20:29 +00:00
if err := c . MetaTable . AlterIndex ( & indexInfo ) ; err != nil {
log . Error ( "alter index into meta table failed, need remove index with buildID" ,
zap . Int64 ( "collectionID" , collID ) , zap . Int64 ( "indexID" , indexID ) ,
2022-06-17 10:08:12 +00:00
zap . Int64 ( "buildID" , buildID ) , zap . Error ( err ) )
if err = retry . Do ( ctx , func ( ) error {
return c . CallRemoveIndexService ( ctx , [ ] UniqueID { buildID } )
} ) ; err != nil {
log . Error ( "remove index failed, need to be resolved manually" , zap . Int64 ( "collectionID" , collID ) ,
2022-07-22 02:20:29 +00:00
zap . Int64 ( "indexID" , indexID ) , zap . Int64 ( "buildID" , buildID ) , zap . Error ( err ) )
2022-06-17 10:08:12 +00:00
return err
}
return err
}
}
return nil
}
2021-08-25 06:41:52 +00:00
func ( c * Core ) checkFlushedSegments ( ctx context . Context ) {
2022-06-17 10:08:12 +00:00
collID2Meta := c . MetaTable . dupCollectionMeta ( )
for collID , collMeta := range collID2Meta {
2022-07-22 02:20:29 +00:00
if len ( collMeta . FieldIDToIndexID ) == 0 {
2021-08-25 06:41:52 +00:00
continue
}
2022-07-22 02:20:29 +00:00
for _ , part := range collMeta . Partitions {
segBinlogs , err := c . CallGetRecoveryInfoService ( ctx , collMeta . CollectionID , part . PartitionID )
2021-08-25 06:41:52 +00:00
if err != nil {
2022-05-05 13:17:50 +00:00
log . Debug ( "failed to get flushed segments from dataCoord" ,
2022-07-22 02:20:29 +00:00
zap . Int64 ( "collection ID" , collMeta . CollectionID ) ,
zap . Int64 ( "partition ID" , part . PartitionID ) ,
2021-08-25 06:41:52 +00:00
zap . Error ( err ) )
2022-03-28 08:41:28 +00:00
continue
}
2022-06-17 10:08:12 +00:00
segIDs := make ( map [ UniqueID ] struct { } )
2022-05-31 08:36:03 +00:00
for _ , segBinlog := range segBinlogs {
2022-06-17 10:08:12 +00:00
segIDs [ segBinlog . GetSegmentID ( ) ] = struct { } { }
2022-07-22 02:20:29 +00:00
err = c . createIndexForSegment ( ctx , collID , part . PartitionID , segBinlog . GetSegmentID ( ) , segBinlog . GetNumOfRows ( ) , segBinlog . GetFieldBinlogs ( ) )
2022-06-17 10:08:12 +00:00
if err != nil {
log . Error ( "createIndexForSegment failed, wait to retry" , zap . Int64 ( "collID" , collID ) ,
2022-07-22 02:20:29 +00:00
zap . Int64 ( "partID" , part . PartitionID ) , zap . Int64 ( "segID" , segBinlog . GetSegmentID ( ) ) , zap . Error ( err ) )
2022-06-17 10:08:12 +00:00
continue
2021-07-03 09:54:25 +00:00
}
}
2022-07-22 02:20:29 +00:00
recycledSegIDs , recycledBuildIDs := c . MetaTable . AlignSegmentsMeta ( collID , part . PartitionID , segIDs )
2022-06-17 10:08:12 +00:00
log . Info ( "there buildIDs should be remove index" , zap . Int64s ( "buildIDs" , recycledBuildIDs ) )
2022-06-20 12:16:12 +00:00
if len ( recycledBuildIDs ) > 0 {
if err := c . CallRemoveIndexService ( ctx , recycledBuildIDs ) ; err != nil {
log . Error ( "CallRemoveIndexService remove indexes on segments failed" ,
zap . Int64s ( "need dropped buildIDs" , recycledBuildIDs ) , zap . Error ( err ) )
continue
}
2022-06-17 10:08:12 +00:00
}
2022-07-22 02:20:29 +00:00
if err := c . MetaTable . RemoveSegments ( collID , part . PartitionID , recycledSegIDs ) ; err != nil {
log . Warn ( "remove segments failed, wait to retry" , zap . Int64 ( "collID" , collID ) , zap . Int64 ( "partID" , part . PartitionID ) ,
2022-06-17 10:08:12 +00:00
zap . Int64s ( "segIDs" , recycledSegIDs ) , zap . Error ( err ) )
continue
}
2021-07-03 09:54:25 +00:00
}
}
2021-05-26 12:14:30 +00:00
}
2022-05-31 08:36:03 +00:00
func ( c * Core ) getSegments ( ctx context . Context , collID typeutil . UniqueID ) ( map [ UniqueID ] UniqueID , map [ UniqueID ] * datapb . SegmentBinlogs , error ) {
2021-07-03 06:36:18 +00:00
collMeta , err := c . MetaTable . GetCollectionByID ( collID , 0 )
if err != nil {
2022-05-31 08:36:03 +00:00
return nil , nil , err
2021-07-03 06:36:18 +00:00
}
2022-05-31 08:36:03 +00:00
segID2PartID := make ( map [ UniqueID ] UniqueID )
segID2Binlog := make ( map [ UniqueID ] * datapb . SegmentBinlogs )
2022-07-22 02:20:29 +00:00
for _ , part := range collMeta . Partitions {
if segs , err := c . CallGetRecoveryInfoService ( ctx , collID , part . PartitionID ) ; err == nil {
2022-05-31 08:36:03 +00:00
for _ , s := range segs {
2022-07-22 02:20:29 +00:00
segID2PartID [ s . SegmentID ] = part . PartitionID
2022-05-31 08:36:03 +00:00
segID2Binlog [ s . SegmentID ] = s
2021-07-03 06:36:18 +00:00
}
} else {
2022-05-31 08:36:03 +00:00
log . Error ( "failed to get flushed segments info from dataCoord" ,
2022-05-06 13:35:51 +00:00
zap . Int64 ( "collection ID" , collID ) ,
2022-07-22 02:20:29 +00:00
zap . Int64 ( "partition ID" , part . PartitionID ) ,
2022-05-06 13:35:51 +00:00
zap . Error ( err ) )
2022-05-31 08:36:03 +00:00
return nil , nil , err
2021-07-03 06:36:18 +00:00
}
}
2022-05-31 08:36:03 +00:00
return segID2PartID , segID2Binlog , nil
2021-07-03 06:36:18 +00:00
}
2021-01-20 01:36:50 +00:00
func ( c * Core ) setMsgStreams ( ) error {
2022-03-04 03:17:56 +00:00
if Params . CommonCfg . RootCoordSubName == "" {
2022-02-01 16:35:43 +00:00
return fmt . Errorf ( "RootCoordSubName is empty" )
2021-01-24 12:26:35 +00:00
}
2021-08-18 06:36:10 +00:00
c . SendTimeTick = func ( t typeutil . Timestamp , reason string ) error {
2021-11-25 02:07:15 +00:00
pc := c . chanTimeTick . listDmlChannels ( )
2021-06-04 07:00:34 +00:00
pt := make ( [ ] uint64 , len ( pc ) )
for i := 0 ; i < len ( pt ) ; i ++ {
pt [ i ] = t
}
ttMsg := internalpb . ChannelTimeTickMsg {
Base : & commonpb . MsgBase {
MsgType : commonpb . MsgType_TimeTick ,
MsgID : 0 , //TODO
Timestamp : t ,
SourceID : c . session . ServerID ,
} ,
2021-06-17 07:54:07 +00:00
ChannelNames : pc ,
Timestamps : pt ,
DefaultTimestamp : t ,
2021-06-04 07:00:34 +00:00
}
2021-11-25 02:07:15 +00:00
return c . chanTimeTick . updateTimeTick ( & ttMsg , reason )
2021-01-20 01:36:50 +00:00
}
2021-09-27 10:10:00 +00:00
c . SendDdCreateCollectionReq = func ( ctx context . Context , req * internalpb . CreateCollectionRequest , channelNames [ ] string ) ( map [ string ] [ ] byte , error ) {
2021-01-20 01:36:50 +00:00
msgPack := ms . MsgPack { }
baseMsg := ms . BaseMsg {
2021-03-25 06:41:46 +00:00
Ctx : ctx ,
2021-01-20 01:36:50 +00:00
BeginTimestamp : req . Base . Timestamp ,
EndTimestamp : req . Base . Timestamp ,
HashValues : [ ] uint32 { 0 } ,
}
2021-06-04 07:00:34 +00:00
msg := & ms . CreateCollectionMsg {
2021-01-20 01:36:50 +00:00
BaseMsg : baseMsg ,
CreateCollectionRequest : * req ,
}
2021-06-04 07:00:34 +00:00
msgPack . Msgs = append ( msgPack . Msgs , msg )
2021-11-25 02:07:15 +00:00
return c . chanTimeTick . broadcastMarkDmlChannels ( channelNames , & msgPack )
2021-01-20 01:36:50 +00:00
}
2021-06-11 08:39:29 +00:00
c . SendDdDropCollectionReq = func ( ctx context . Context , req * internalpb . DropCollectionRequest , channelNames [ ] string ) error {
2021-01-20 01:36:50 +00:00
msgPack := ms . MsgPack { }
baseMsg := ms . BaseMsg {
2021-03-25 06:41:46 +00:00
Ctx : ctx ,
2021-01-20 01:36:50 +00:00
BeginTimestamp : req . Base . Timestamp ,
EndTimestamp : req . Base . Timestamp ,
HashValues : [ ] uint32 { 0 } ,
}
2021-06-04 07:00:34 +00:00
msg := & ms . DropCollectionMsg {
2021-01-20 01:36:50 +00:00
BaseMsg : baseMsg ,
DropCollectionRequest : * req ,
}
2021-06-04 07:00:34 +00:00
msgPack . Msgs = append ( msgPack . Msgs , msg )
2021-11-25 02:07:15 +00:00
return c . chanTimeTick . broadcastDmlChannels ( channelNames , & msgPack )
2021-01-20 01:36:50 +00:00
}
2021-06-11 08:39:29 +00:00
c . SendDdCreatePartitionReq = func ( ctx context . Context , req * internalpb . CreatePartitionRequest , channelNames [ ] string ) error {
2021-01-20 01:36:50 +00:00
msgPack := ms . MsgPack { }
baseMsg := ms . BaseMsg {
2021-03-25 06:41:46 +00:00
Ctx : ctx ,
2021-01-20 01:36:50 +00:00
BeginTimestamp : req . Base . Timestamp ,
EndTimestamp : req . Base . Timestamp ,
HashValues : [ ] uint32 { 0 } ,
}
2021-06-04 07:00:34 +00:00
msg := & ms . CreatePartitionMsg {
2021-01-20 01:36:50 +00:00
BaseMsg : baseMsg ,
CreatePartitionRequest : * req ,
}
2021-06-04 07:00:34 +00:00
msgPack . Msgs = append ( msgPack . Msgs , msg )
2021-11-25 02:07:15 +00:00
return c . chanTimeTick . broadcastDmlChannels ( channelNames , & msgPack )
2021-01-20 01:36:50 +00:00
}
2021-06-11 08:39:29 +00:00
c . SendDdDropPartitionReq = func ( ctx context . Context , req * internalpb . DropPartitionRequest , channelNames [ ] string ) error {
2021-01-20 01:36:50 +00:00
msgPack := ms . MsgPack { }
baseMsg := ms . BaseMsg {
2021-03-25 06:41:46 +00:00
Ctx : ctx ,
2021-01-20 01:36:50 +00:00
BeginTimestamp : req . Base . Timestamp ,
EndTimestamp : req . Base . Timestamp ,
HashValues : [ ] uint32 { 0 } ,
}
2021-06-04 07:00:34 +00:00
msg := & ms . DropPartitionMsg {
2021-01-20 01:36:50 +00:00
BaseMsg : baseMsg ,
DropPartitionRequest : * req ,
}
2021-06-04 07:00:34 +00:00
msgPack . Msgs = append ( msgPack . Msgs , msg )
2021-11-25 02:07:15 +00:00
return c . chanTimeTick . broadcastDmlChannels ( channelNames , & msgPack )
2021-01-20 01:36:50 +00:00
}
return nil
}
2021-09-23 07:10:00 +00:00
// SetNewProxyClient set client to create proxy
2021-06-22 11:08:03 +00:00
func ( c * Core ) SetNewProxyClient ( f func ( sess * sessionutil . Session ) ( types . Proxy , error ) ) {
2021-05-26 12:14:30 +00:00
if c . NewProxyClient == nil {
c . NewProxyClient = f
} else {
2021-06-01 03:04:31 +00:00
log . Debug ( "NewProxyClient has already set" )
2021-05-26 12:14:30 +00:00
}
}
2022-04-06 07:33:32 +00:00
// SetDataCoord set dataCoord.
2021-06-21 10:22:13 +00:00
func ( c * Core ) SetDataCoord ( ctx context . Context , s types . DataCoord ) error {
2021-06-25 08:48:10 +00:00
initCh := make ( chan struct { } )
go func ( ) {
for {
if err := s . Init ( ) ; err == nil {
if err := s . Start ( ) ; err == nil {
close ( initCh )
2021-10-13 02:50:41 +00:00
log . Debug ( "RootCoord connected to DataCoord" )
2021-06-25 08:48:10 +00:00
return
}
}
2021-10-13 02:50:41 +00:00
log . Debug ( "Retrying RootCoord connection to DataCoord" )
2021-06-25 08:48:10 +00:00
}
} ( )
2021-03-08 07:46:51 +00:00
2022-05-31 08:36:03 +00:00
c . CallGetFlushedSegmentsService = func ( ctx context . Context , collID , partID typeutil . UniqueID ) ( retSegIDs [ ] typeutil . UniqueID , retErr error ) {
2021-05-26 12:14:30 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
2022-05-31 08:36:03 +00:00
retErr = fmt . Errorf ( "get flushed segments from data coord panic, msg = %v" , err )
2021-05-26 12:14:30 +00:00
}
} ( )
2021-06-25 08:48:10 +00:00
<- initCh
2022-05-31 08:36:03 +00:00
req := & datapb . GetFlushedSegmentsRequest {
2021-03-08 07:46:51 +00:00
Base : & commonpb . MsgBase {
2022-05-31 08:36:03 +00:00
MsgType : 0 , //TODO,msg type
2021-03-08 07:46:51 +00:00
MsgID : 0 ,
2022-05-31 08:36:03 +00:00
Timestamp : 0 ,
2021-05-25 07:06:05 +00:00
SourceID : c . session . ServerID ,
2021-03-08 07:46:51 +00:00
} ,
2022-05-31 08:36:03 +00:00
CollectionID : collID ,
PartitionID : partID ,
2021-03-08 07:46:51 +00:00
}
2022-05-31 08:36:03 +00:00
rsp , err := s . GetFlushedSegments ( ctx , req )
if err != nil {
return nil , err
2021-03-08 07:46:51 +00:00
}
2022-05-31 08:36:03 +00:00
if rsp . Status . ErrorCode != commonpb . ErrorCode_Success {
return nil , fmt . Errorf ( "get flushed segments from data coord failed, reason = %s" , rsp . Status . Reason )
2021-03-08 07:46:51 +00:00
}
2022-05-31 08:36:03 +00:00
return rsp . Segments , nil
2021-03-08 07:46:51 +00:00
}
2021-07-03 06:36:18 +00:00
2022-05-31 08:36:03 +00:00
c . CallGetRecoveryInfoService = func ( ctx context . Context , collID , partID typeutil . UniqueID ) ( [ ] * datapb . SegmentBinlogs , error ) {
getSegmentInfoReq := & datapb . GetRecoveryInfoRequest {
2021-07-03 06:36:18 +00:00
Base : & commonpb . MsgBase {
2022-05-31 08:36:03 +00:00
MsgType : 0 , //TODO, msg type
2021-07-03 06:36:18 +00:00
MsgID : 0 ,
Timestamp : 0 ,
SourceID : c . session . ServerID ,
} ,
CollectionID : collID ,
PartitionID : partID ,
}
2022-05-31 08:36:03 +00:00
resp , err := s . GetRecoveryInfo ( ctx , getSegmentInfoReq )
2021-07-03 06:36:18 +00:00
if err != nil {
2022-03-15 10:51:21 +00:00
return nil , err
2021-07-03 06:36:18 +00:00
}
2022-05-31 08:36:03 +00:00
if resp . Status . ErrorCode != commonpb . ErrorCode_Success {
return nil , errors . New ( resp . Status . Reason )
2021-07-03 06:36:18 +00:00
}
2022-05-31 08:36:03 +00:00
return resp . Binlogs , nil
2021-07-03 06:36:18 +00:00
}
2022-08-22 06:42:52 +00:00
c . CallWatchChannels = func ( ctx context . Context , collectionID int64 , channelNames [ ] string , startPositions [ ] * commonpb . KeyDataPair ) ( retErr error ) {
2021-11-10 16:54:45 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "watch channels panic, msg = %v" , err )
}
} ( )
<- initCh
req := & datapb . WatchChannelsRequest {
2022-08-22 06:42:52 +00:00
CollectionID : collectionID ,
ChannelNames : channelNames ,
StartPositions : startPositions ,
2021-11-10 16:54:45 +00:00
}
rsp , err := s . WatchChannels ( ctx , req )
if err != nil {
return err
}
if rsp . Status . ErrorCode != commonpb . ErrorCode_Success {
return fmt . Errorf ( "data coord watch channels failed, reason = %s" , rsp . Status . Reason )
}
return nil
}
2022-04-25 03:07:47 +00:00
2022-04-01 03:33:28 +00:00
c . CallImportService = func ( ctx context . Context , req * datapb . ImportTaskRequest ) * datapb . ImportTaskResponse {
2022-03-22 07:11:24 +00:00
resp := & datapb . ImportTaskResponse {
Status : & commonpb . Status {
ErrorCode : commonpb . ErrorCode_Success ,
} ,
2022-03-21 07:47:23 +00:00
}
defer func ( ) {
if err := recover ( ) ; err != nil {
2022-03-22 07:11:24 +00:00
resp . Status . ErrorCode = commonpb . ErrorCode_UnexpectedError
resp . Status . Reason = "assign import task to data coord panic"
2022-03-21 07:47:23 +00:00
}
} ( )
2022-03-22 07:11:24 +00:00
resp , _ = s . Import ( ctx , req )
return resp
2022-03-21 07:47:23 +00:00
}
2022-04-25 03:07:47 +00:00
c . CallFlushOnCollection = func ( ctx context . Context , cID int64 , segIDs [ ] int64 ) error {
resp , err := s . Flush ( ctx , & datapb . FlushRequest {
Base : & commonpb . MsgBase {
MsgType : commonpb . MsgType_Flush ,
SourceID : c . session . ServerID ,
} ,
DbID : 0 ,
SegmentIDs : segIDs ,
CollectionID : cID ,
} )
if err != nil {
return errors . New ( "failed to call flush to data coordinator: " + err . Error ( ) )
}
if resp . Status . ErrorCode != commonpb . ErrorCode_Success {
return errors . New ( resp . Status . Reason )
}
log . Info ( "flush on collection succeed" , zap . Int64 ( "collection ID" , cID ) )
return nil
}
2022-06-15 13:38:10 +00:00
c . CallAddSegRefLock = func ( ctx context . Context , taskID int64 , segIDs [ ] int64 ) ( retErr error ) {
2022-06-15 04:20:10 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "add seg ref lock panic, msg = %v" , err )
}
} ( )
<- initCh
log . Info ( "acquiring seg lock" ,
zap . Int64s ( "segment IDs" , segIDs ) ,
zap . Int64 ( "node ID" , c . session . ServerID ) )
resp , _ := s . AcquireSegmentLock ( ctx , & datapb . AcquireSegmentLockRequest {
SegmentIDs : segIDs ,
NodeID : c . session . ServerID ,
2022-06-15 13:38:10 +00:00
TaskID : taskID ,
2022-06-15 04:20:10 +00:00
} )
if resp . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( "failed to acquire segment lock %s" , resp . GetReason ( ) )
}
log . Info ( "acquire seg lock succeed" ,
zap . Int64s ( "segment IDs" , segIDs ) ,
zap . Int64 ( "node ID" , c . session . ServerID ) )
return nil
}
2022-06-15 13:38:10 +00:00
c . CallReleaseSegRefLock = func ( ctx context . Context , taskID int64 , segIDs [ ] int64 ) ( retErr error ) {
2022-06-15 04:20:10 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "release seg ref lock panic, msg = %v" , err )
}
} ( )
<- initCh
log . Info ( "releasing seg lock" ,
zap . Int64s ( "segment IDs" , segIDs ) ,
zap . Int64 ( "node ID" , c . session . ServerID ) )
resp , _ := s . ReleaseSegmentLock ( ctx , & datapb . ReleaseSegmentLockRequest {
SegmentIDs : segIDs ,
NodeID : c . session . ServerID ,
2022-06-15 13:38:10 +00:00
TaskID : taskID ,
2022-06-15 04:20:10 +00:00
} )
if resp . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( "failed to release segment lock %s" , resp . GetReason ( ) )
}
log . Info ( "release seg lock succeed" ,
zap . Int64s ( "segment IDs" , segIDs ) ,
zap . Int64 ( "node ID" , c . session . ServerID ) )
return nil
}
2021-01-24 12:26:35 +00:00
return nil
}
2022-06-15 04:20:10 +00:00
// SetIndexCoord sets IndexCoord.
2021-06-21 09:28:03 +00:00
func ( c * Core ) SetIndexCoord ( s types . IndexCoord ) error {
2021-06-25 08:48:10 +00:00
initCh := make ( chan struct { } )
go func ( ) {
for {
if err := s . Init ( ) ; err == nil {
if err := s . Start ( ) ; err == nil {
close ( initCh )
2021-10-13 02:50:41 +00:00
log . Debug ( "RootCoord connected to IndexCoord" )
2021-06-25 08:48:10 +00:00
return
}
}
2021-10-13 02:50:41 +00:00
log . Debug ( "Retrying RootCoord connection to IndexCoord" )
2021-06-25 08:48:10 +00:00
}
} ( )
2022-07-22 02:20:29 +00:00
c . CallBuildIndexService = func ( ctx context . Context , segID UniqueID , binlog [ ] string , field * model . Field , idxInfo * model . Index , numRows int64 ) ( retID typeutil . UniqueID , retErr error ) {
2021-05-26 12:14:30 +00:00
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "build index panic, msg = %v" , err )
}
} ( )
2021-06-25 08:48:10 +00:00
<- initCh
2021-02-26 09:44:24 +00:00
rsp , err := s . BuildIndex ( ctx , & indexpb . BuildIndexRequest {
2021-01-24 12:26:35 +00:00
DataPaths : binlog ,
2021-05-15 10:08:08 +00:00
TypeParams : field . TypeParams ,
IndexParams : idxInfo . IndexParams ,
IndexID : idxInfo . IndexID ,
IndexName : idxInfo . IndexName ,
2021-12-09 06:19:40 +00:00
NumRows : numRows ,
2022-07-22 02:20:29 +00:00
FieldSchema : model . MarshalFieldModel ( field ) ,
2022-05-31 08:36:03 +00:00
SegmentID : segID ,
2021-01-24 12:26:35 +00:00
} )
if err != nil {
2021-09-07 03:16:37 +00:00
return retID , err
2021-01-24 12:26:35 +00:00
}
2021-03-10 14:06:22 +00:00
if rsp . Status . ErrorCode != commonpb . ErrorCode_Success {
2021-11-16 06:25:17 +00:00
return retID , fmt . Errorf ( "buildIndex from index service failed, error = %s" , rsp . Status . Reason )
2021-01-24 12:26:35 +00:00
}
2021-09-07 03:16:37 +00:00
return rsp . IndexBuildID , nil
2021-01-24 12:26:35 +00:00
}
2021-02-20 07:38:44 +00:00
2021-05-26 12:14:30 +00:00
c . CallDropIndexService = func ( ctx context . Context , indexID typeutil . UniqueID ) ( retErr error ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "drop index from index service panic, msg = %v" , err )
}
} ( )
2021-06-25 08:48:10 +00:00
<- initCh
2021-02-26 09:44:24 +00:00
rsp , err := s . DropIndex ( ctx , & indexpb . DropIndexRequest {
2021-02-20 07:38:44 +00:00
IndexID : indexID ,
} )
if err != nil {
2021-09-07 03:16:37 +00:00
return err
2021-02-20 07:38:44 +00:00
}
2021-03-10 14:06:22 +00:00
if rsp . ErrorCode != commonpb . ErrorCode_Success {
2021-09-07 03:16:37 +00:00
return fmt . Errorf ( rsp . Reason )
2021-02-20 07:38:44 +00:00
}
2021-09-07 03:16:37 +00:00
return nil
2021-02-20 07:38:44 +00:00
}
2022-03-28 08:41:28 +00:00
c . CallGetIndexStatesService = func ( ctx context . Context , IndexBuildIDs [ ] int64 ) ( idxInfo [ ] * indexpb . IndexInfo , retErr error ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "get index state from index service panic, msg = %v" , err )
}
} ( )
<- initCh
res , err := s . GetIndexStates ( ctx , & indexpb . GetIndexStatesRequest {
IndexBuildIDs : IndexBuildIDs ,
} )
if err != nil {
log . Error ( "RootCoord failed to get index states from IndexCoord." , zap . Error ( err ) )
return nil , err
}
2022-03-31 05:51:28 +00:00
log . Debug ( "got index states" , zap . String ( "get index state result" , res . String ( ) ) )
2022-03-28 08:41:28 +00:00
if res . GetStatus ( ) . GetErrorCode ( ) != commonpb . ErrorCode_Success {
log . Error ( "Get index states failed." ,
zap . String ( "error_code" , res . GetStatus ( ) . GetErrorCode ( ) . String ( ) ) ,
zap . String ( "reason" , res . GetStatus ( ) . GetReason ( ) ) )
return nil , fmt . Errorf ( res . GetStatus ( ) . GetErrorCode ( ) . String ( ) )
}
return res . GetStates ( ) , nil
}
2022-06-17 10:08:12 +00:00
c . CallRemoveIndexService = func ( ctx context . Context , buildIDs [ ] UniqueID ) ( retErr error ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
2022-06-17 17:24:11 +00:00
retErr = fmt . Errorf ( "remove index from index service panic, msg = %v" , err )
2022-06-17 10:08:12 +00:00
}
} ( )
<- initCh
status , err := s . RemoveIndex ( ctx , & indexpb . RemoveIndexRequest {
BuildIDs : buildIDs ,
} )
if err != nil {
return err
}
if status . GetErrorCode ( ) != commonpb . ErrorCode_Success {
return fmt . Errorf ( status . Reason )
}
return nil
}
2021-01-24 12:26:35 +00:00
return nil
}
2022-05-05 13:17:50 +00:00
// SetQueryCoord sets up queryCoord and queryCoord related function calls.
2021-06-22 08:44:09 +00:00
func ( c * Core ) SetQueryCoord ( s types . QueryCoord ) error {
2021-06-25 08:48:10 +00:00
initCh := make ( chan struct { } )
go func ( ) {
for {
if err := s . Init ( ) ; err == nil {
if err := s . Start ( ) ; err == nil {
close ( initCh )
2021-10-13 02:50:41 +00:00
log . Debug ( "RootCoord connected to QueryCoord" )
2021-06-25 08:48:10 +00:00
return
}
}
2021-10-13 02:50:41 +00:00
log . Debug ( "Retrying RootCoord connection to QueryCoord" )
2021-06-25 08:48:10 +00:00
}
} ( )
2021-05-26 12:14:30 +00:00
c . CallReleaseCollectionService = func ( ctx context . Context , ts typeutil . Timestamp , dbID typeutil . UniqueID , collectionID typeutil . UniqueID ) ( retErr error ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "release collection from query service panic, msg = %v" , err )
}
} ( )
2021-06-25 08:48:10 +00:00
<- initCh
2021-02-05 06:09:55 +00:00
req := & querypb . ReleaseCollectionRequest {
Base : & commonpb . MsgBase {
2021-03-10 06:45:35 +00:00
MsgType : commonpb . MsgType_ReleaseCollection ,
2021-02-05 06:09:55 +00:00
MsgID : 0 , //TODO, msg ID
Timestamp : ts ,
2021-05-25 07:06:05 +00:00
SourceID : c . session . ServerID ,
2021-02-05 06:09:55 +00:00
} ,
DbID : dbID ,
CollectionID : collectionID ,
}
2021-02-26 09:44:24 +00:00
rsp , err := s . ReleaseCollection ( ctx , req )
2021-02-05 06:09:55 +00:00
if err != nil {
2021-09-07 03:16:37 +00:00
return err
2021-02-05 06:09:55 +00:00
}
2021-03-10 14:06:22 +00:00
if rsp . ErrorCode != commonpb . ErrorCode_Success {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "releaseCollection from query service failed, error = %s" , rsp . Reason )
2021-02-05 06:09:55 +00:00
}
2021-09-07 03:16:37 +00:00
return nil
2021-02-05 06:09:55 +00:00
}
2021-06-22 08:08:08 +00:00
c . CallReleasePartitionService = func ( ctx context . Context , ts typeutil . Timestamp , dbID , collectionID typeutil . UniqueID , partitionIDs [ ] typeutil . UniqueID ) ( retErr error ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "release partition from query service panic, msg = %v" , err )
}
} ( )
2021-06-25 08:48:10 +00:00
<- initCh
2021-06-22 08:08:08 +00:00
req := & querypb . ReleasePartitionsRequest {
Base : & commonpb . MsgBase {
MsgType : commonpb . MsgType_ReleasePartitions ,
MsgID : 0 , //TODO, msg ID
Timestamp : ts ,
SourceID : c . session . ServerID ,
} ,
DbID : dbID ,
CollectionID : collectionID ,
PartitionIDs : partitionIDs ,
}
rsp , err := s . ReleasePartitions ( ctx , req )
if err != nil {
2021-09-07 03:16:37 +00:00
return err
2021-06-22 08:08:08 +00:00
}
if rsp . ErrorCode != commonpb . ErrorCode_Success {
2021-11-16 06:25:17 +00:00
return fmt . Errorf ( "releasePartitions from query service failed, error = %s" , rsp . Reason )
2021-06-22 08:08:08 +00:00
}
2021-09-07 03:16:37 +00:00
return nil
2021-06-22 08:08:08 +00:00
}
2022-05-05 13:17:50 +00:00
c . CallGetSegmentInfoService = func ( ctx context . Context , collectionID int64 , segIDs [ ] int64 ) ( retResp * querypb . GetSegmentInfoResponse , retErr error ) {
defer func ( ) {
if err := recover ( ) ; err != nil {
retErr = fmt . Errorf ( "call segment info service panic, msg = %v" , err )
}
} ( )
<- initCh
resp , err := s . GetSegmentInfo ( ctx , & querypb . GetSegmentInfoRequest {
Base : & commonpb . MsgBase {
MsgType : commonpb . MsgType_GetSegmentState ,
SourceID : c . session . ServerID ,
} ,
CollectionID : collectionID ,
SegmentIDs : segIDs ,
} )
return resp , err
}
2021-02-05 06:09:55 +00:00
return nil
}
2021-05-15 10:08:08 +00:00
// BuildIndex will check row num and call build index service
2022-07-22 02:20:29 +00:00
func ( c * Core ) BuildIndex ( ctx context . Context , segID UniqueID , numRows int64 , binlogs [ ] * datapb . FieldBinlog , field * model . Field , idxInfo * model . Index , isFlush bool ) ( typeutil . UniqueID , error ) {
2021-11-15 11:26:49 +00:00
log . Debug ( "start build index" , zap . String ( "index name" , idxInfo . IndexName ) ,
zap . String ( "field name" , field . Name ) , zap . Int64 ( "segment id" , segID ) )
2021-06-30 08:18:13 +00:00
sp , ctx := trace . StartSpanFromContext ( ctx )
defer sp . Finish ( )
2021-05-15 10:08:08 +00:00
if c . MetaTable . IsSegmentIndexed ( segID , field , idxInfo . IndexParams ) {
2022-07-22 02:20:29 +00:00
info , err := c . MetaTable . GetSegmentIndexInfoByID ( segID , field . FieldID , idxInfo . IndexName )
return info . SegmentIndexes [ segID ] . BuildID , err
2021-05-15 10:08:08 +00:00
}
2022-05-31 08:36:03 +00:00
var bldID UniqueID
var err error
if numRows < Params . RootCoordCfg . MinSegmentSizeToEnableIndex {
log . Debug ( "num of rows is less than MinSegmentSizeToEnableIndex" , zap . Int64 ( "num rows" , numRows ) )
2021-05-15 10:08:08 +00:00
} else {
2022-05-31 08:36:03 +00:00
binLogs := make ( [ ] string , 0 )
for _ , fieldBinLog := range binlogs {
2022-07-22 02:20:29 +00:00
if fieldBinLog . GetFieldID ( ) == field . FieldID {
2022-05-31 08:36:03 +00:00
for _ , binLog := range fieldBinLog . GetBinlogs ( ) {
binLogs = append ( binLogs , binLog . LogPath )
}
break
}
2021-05-15 10:08:08 +00:00
}
2022-05-31 08:36:03 +00:00
bldID , err = c . CallBuildIndexService ( ctx , segID , binLogs , field , idxInfo , numRows )
2021-05-15 10:08:08 +00:00
}
2022-05-31 08:36:03 +00:00
return bldID , err
2021-05-15 10:08:08 +00:00
}
2021-11-23 15:01:15 +00:00
// ExpireMetaCache will call invalidate collection meta cache
2022-05-19 02:13:56 +00:00
func ( c * Core ) ExpireMetaCache ( ctx context . Context , collNames [ ] string , collectionID UniqueID , ts typeutil . Timestamp ) error {
// if collectionID is specified, invalidate all the collection meta cache with the specified collectionID and return
if collectionID != InvalidCollectionID {
req := proxypb . InvalidateCollMetaCacheRequest {
Base : & commonpb . MsgBase {
Timestamp : ts ,
SourceID : c . session . ServerID ,
} ,
CollectionID : collectionID ,
}
return c . proxyClientManager . InvalidateCollectionMetaCache ( ctx , & req )
}
// if only collNames are specified, invalidate the collection meta cache with the specified collectionName
2021-11-23 15:01:15 +00:00
for _ , collName := range collNames {
req := proxypb . InvalidateCollMetaCacheRequest {
Base : & commonpb . MsgBase {
MsgType : 0 , //TODO, msg type
MsgID : 0 , //TODO, msg id
Timestamp : ts ,
SourceID : c . session . ServerID ,
} ,
CollectionName : collName ,
}
2022-05-19 02:13:56 +00:00
err := c . proxyClientManager . InvalidateCollectionMetaCache ( ctx , & req )
if err != nil {
// TODO: try to expire all or directly return err?
return err
}
2021-11-23 15:01:15 +00:00
}
2022-05-19 02:13:56 +00:00
return nil
2021-11-23 15:01:15 +00:00
}
2021-06-17 08:47:57 +00:00
// Register register rootcoord at etcd
2021-05-25 07:06:05 +00:00
func ( c * Core ) Register ( ) error {
2021-12-15 03:47:10 +00:00
c . session . Register ( )
go c . session . LivenessCheck ( c . ctx , func ( ) {
log . Error ( "Root Coord disconnected from etcd, process will exit" , zap . Int64 ( "Server Id" , c . session . ServerID ) )
if err := c . Stop ( ) ; err != nil {
log . Fatal ( "failed to stop server" , zap . Error ( err ) )
}
// manually send signal to starter goroutine
2021-12-29 06:35:21 +00:00
if c . session . TriggerKill {
2022-03-17 09:17:22 +00:00
if p , err := os . FindProcess ( os . Getpid ( ) ) ; err == nil {
p . Signal ( syscall . SIGINT )
}
2021-12-29 06:35:21 +00:00
}
2021-12-15 03:47:10 +00:00
} )
2022-01-18 04:09:37 +00:00
c . UpdateStateCode ( internalpb . StateCode_Healthy )
log . Debug ( "RootCoord start successfully " , zap . String ( "State Code" , internalpb . StateCode_Healthy . String ( ) ) )
2021-12-15 03:47:10 +00:00
return nil
}
2021-12-31 06:23:55 +00:00
// SetEtcdClient sets the etcdCli of Core
2021-12-29 06:35:21 +00:00
func ( c * Core ) SetEtcdClient ( etcdClient * clientv3 . Client ) {
c . etcdCli = etcdClient
}
2021-12-15 03:47:10 +00:00
func ( c * Core ) initSession ( ) error {
2022-02-07 02:09:45 +00:00
c . session = sessionutil . NewSession ( c . ctx , Params . EtcdCfg . MetaRootPath , c . etcdCli )
2021-06-03 11:01:33 +00:00
if c . session == nil {
2021-10-13 02:50:41 +00:00
return fmt . Errorf ( "session is nil, the etcd client connection may have failed" )
2021-06-03 11:01:33 +00:00
}
2021-12-29 06:35:21 +00:00
c . session . Init ( typeutil . RootCoordRole , Params . RootCoordCfg . Address , true , true )
2022-02-07 02:09:45 +00:00
Params . SetLogger ( c . session . ServerID )
2021-05-25 07:06:05 +00:00
return nil
}
2021-09-23 07:10:00 +00:00
// Init initialize routine
2021-01-24 12:26:35 +00:00
func ( c * Core ) Init ( ) error {
2021-12-14 07:31:07 +00:00
var initError error
2021-09-15 14:05:49 +00:00
if c . kvBaseCreate == nil {
c . kvBaseCreate = func ( root string ) ( kv . TxnKV , error ) {
2021-12-29 06:35:21 +00:00
return etcdkv . NewEtcdKV ( c . etcdCli , root ) , nil
2021-09-15 14:05:49 +00:00
}
}
2022-03-25 03:03:25 +00:00
if c . metaKVCreate == nil {
c . metaKVCreate = func ( root string ) ( kv . MetaKv , error ) {
return etcdkv . NewEtcdKV ( c . etcdCli , root ) , nil
}
}
2021-01-19 06:44:03 +00:00
c . initOnce . Do ( func ( ) {
2021-12-15 03:47:10 +00:00
if err := c . initSession ( ) ; err != nil {
initError = err
log . Error ( "RootCoord init session failed" , zap . Error ( err ) )
return
}
2021-02-26 07:17:47 +00:00
connectEtcdFn := func ( ) error {
2022-02-07 02:09:45 +00:00
if c . kvBase , initError = c . kvBaseCreate ( Params . EtcdCfg . KvRootPath ) ; initError != nil {
2022-03-25 03:03:25 +00:00
log . Error ( "RootCoord failed to new EtcdKV for kvBase" , zap . Any ( "reason" , initError ) )
return initError
}
if c . impTaskKv , initError = c . metaKVCreate ( Params . EtcdCfg . KvRootPath ) ; initError != nil {
log . Error ( "RootCoord failed to new EtcdKV for MetaKV" , zap . Any ( "reason" , initError ) )
2021-09-15 14:05:49 +00:00
return initError
}
2022-07-22 02:20:29 +00:00
2022-08-20 02:24:51 +00:00
var catalog metastore . RootCoordCatalog
2022-08-11 04:12:38 +00:00
switch Params . MetaStoreCfg . MetaStoreType {
case util . MetaStoreTypeEtcd :
var metaKV kv . TxnKV
metaKV , initError = c . kvBaseCreate ( Params . EtcdCfg . MetaRootPath )
if initError != nil {
log . Error ( "RootCoord failed to new EtcdKV" , zap . Any ( "reason" , initError ) )
return initError
}
2022-08-20 02:24:51 +00:00
var ss * rootcoord . SuffixSnapshot
if ss , initError = rootcoord . NewSuffixSnapshot ( metaKV , "_ts" , Params . EtcdCfg . MetaRootPath , "snapshots" ) ; initError != nil {
2022-08-11 04:12:38 +00:00
log . Error ( "RootCoord failed to new suffixSnapshot" , zap . Error ( initError ) )
return initError
}
2022-08-20 02:24:51 +00:00
catalog = & rootcoord . Catalog { Txn : metaKV , Snapshot : ss }
2022-08-11 04:12:38 +00:00
case util . MetaStoreTypeMysql :
// connect to database
err := dbcore . Connect ( & Params . DBCfg )
if err != nil {
return err
}
2022-08-20 02:24:51 +00:00
catalog = rootcoord2 . NewTableCatalog ( dbcore . NewTxImpl ( ) , dao . NewMetaDomain ( ) )
2022-08-11 04:12:38 +00:00
default :
return fmt . Errorf ( "not supported meta store: %s" , Params . MetaStoreCfg . MetaStoreType )
2021-02-26 07:17:47 +00:00
}
2022-08-11 04:12:38 +00:00
if c . MetaTable , initError = NewMetaTable ( c . ctx , catalog ) ; initError != nil {
2021-11-19 04:11:12 +00:00
log . Error ( "RootCoord failed to new MetaTable" , zap . Any ( "reason" , initError ) )
2021-08-13 03:04:09 +00:00
return initError
}
2021-02-26 07:17:47 +00:00
return nil
2021-01-19 06:44:03 +00:00
}
2022-02-07 02:09:45 +00:00
log . Debug ( "RootCoord, Connecting to Etcd" , zap . String ( "kv root" , Params . EtcdCfg . KvRootPath ) , zap . String ( "meta root" , Params . EtcdCfg . MetaRootPath ) )
2022-05-05 01:31:51 +00:00
err := retry . Do ( c . ctx , connectEtcdFn , retry . Attempts ( 100 ) )
2021-02-26 07:17:47 +00:00
if err != nil {
2021-01-19 06:44:03 +00:00
return
}
2021-10-13 02:50:41 +00:00
log . Debug ( "RootCoord, Setting TSO and ID Allocator" )
2022-02-07 02:09:45 +00:00
kv := tsoutil . NewTSOKVBase ( c . etcdCli , Params . EtcdCfg . KvRootPath , "gid" )
2021-08-13 03:04:09 +00:00
idAllocator := allocator . NewGlobalIDAllocator ( "idTimestamp" , kv )
2021-04-08 09:31:39 +00:00
if initError = idAllocator . Initialize ( ) ; initError != nil {
2021-01-19 06:44:03 +00:00
return
}
2021-05-20 06:14:14 +00:00
c . IDAllocator = func ( count uint32 ) ( typeutil . UniqueID , typeutil . UniqueID , error ) {
2021-04-08 09:31:39 +00:00
return idAllocator . Alloc ( count )
}
2021-05-20 06:14:14 +00:00
c . IDAllocatorUpdate = func ( ) error {
2021-04-08 09:31:39 +00:00
return idAllocator . UpdateID ( )
}
2022-02-07 02:09:45 +00:00
kv = tsoutil . NewTSOKVBase ( c . etcdCli , Params . EtcdCfg . KvRootPath , "tso" )
2021-08-13 03:04:09 +00:00
tsoAllocator := tso . NewGlobalTSOAllocator ( "timestamp" , kv )
2021-04-08 09:31:39 +00:00
if initError = tsoAllocator . Initialize ( ) ; initError != nil {
2021-01-19 06:44:03 +00:00
return
}
2021-05-20 06:14:14 +00:00
c . TSOAllocator = func ( count uint32 ) ( typeutil . Timestamp , error ) {
2021-04-08 09:31:39 +00:00
return tsoAllocator . Alloc ( count )
}
2021-05-20 06:14:14 +00:00
c . TSOAllocatorUpdate = func ( ) error {
2021-04-08 09:31:39 +00:00
return tsoAllocator . UpdateTSO ( )
}
2022-03-02 13:11:57 +00:00
c . TSOGetLastSavedTime = func ( ) time . Time {
return tsoAllocator . GetLastSavedTime ( )
}
2021-04-08 09:31:39 +00:00
2022-04-07 14:05:32 +00:00
c . factory . Init ( & Params )
2021-06-04 07:00:34 +00:00
2021-11-02 07:50:30 +00:00
chanMap := c . MetaTable . ListCollectionPhysicalChannels ( )
2022-04-07 14:05:32 +00:00
c . chanTimeTick = newTimeTickSync ( c . ctx , c . session . ServerID , c . factory , chanMap )
2022-01-18 06:47:36 +00:00
c . chanTimeTick . addSession ( c . session )
2021-05-26 12:14:30 +00:00
c . proxyClientManager = newProxyClientManager ( c )
2021-06-22 08:08:08 +00:00
log . Debug ( "RootCoord, set proxy manager" )
2021-12-29 06:35:21 +00:00
c . proxyManager = newProxyManager (
2021-05-26 12:14:30 +00:00
c . ctx ,
2021-12-29 06:35:21 +00:00
c . etcdCli ,
2022-01-27 03:25:41 +00:00
c . chanTimeTick . initSessions ,
2021-05-26 12:14:30 +00:00
c . proxyClientManager . GetProxyClients ,
)
2022-01-27 03:25:41 +00:00
c . proxyManager . AddSessionFunc ( c . chanTimeTick . addSession , c . proxyClientManager . AddProxyClient )
c . proxyManager . DelSessionFunc ( c . chanTimeTick . delSession , c . proxyClientManager . DelProxyClient )
2021-05-21 08:08:12 +00:00
2021-09-03 09:15:26 +00:00
c . metricsCacheManager = metricsinfo . NewMetricsCacheManager ( )
2021-01-20 01:36:50 +00:00
initError = c . setMsgStreams ( )
2021-08-13 03:04:09 +00:00
if initError != nil {
return
}
2022-03-21 07:47:23 +00:00
c . importManager = newImportManager (
c . ctx ,
2022-03-25 03:03:25 +00:00
c . impTaskKv ,
2022-04-24 03:29:45 +00:00
c . IDAllocator ,
2022-03-21 07:47:23 +00:00
c . CallImportService ,
2022-06-14 08:18:09 +00:00
c . getCollectionName ,
2022-03-21 07:47:23 +00:00
)
2022-04-24 03:29:45 +00:00
c . importManager . init ( c . ctx )
2022-04-21 11:57:42 +00:00
2022-04-20 05:03:40 +00:00
// init data
2022-04-21 11:57:42 +00:00
initError = c . initData ( )
2022-04-20 05:03:40 +00:00
if initError != nil {
return
}
2022-08-04 03:04:34 +00:00
if initError = c . initRbac ( ) ; initError != nil {
return
}
log . Debug ( "RootCoord init user root done" )
2021-01-19 06:44:03 +00:00
} )
2021-11-19 04:11:12 +00:00
if initError != nil {
2021-06-22 08:08:08 +00:00
log . Debug ( "RootCoord init error" , zap . Error ( initError ) )
2021-01-26 11:24:09 +00:00
}
2021-11-19 04:11:12 +00:00
log . Debug ( "RootCoord init done" )
2021-01-19 06:44:03 +00:00
return initError
}
2022-04-21 11:57:42 +00:00
func ( c * Core ) initData ( ) error {
credInfo , _ := c . MetaTable . getCredential ( util . UserRoot )
if credInfo == nil {
log . Debug ( "RootCoord init user root" )
encryptedRootPassword , _ := crypto . PasswordEncrypt ( util . DefaultRootPassword )
err := c . MetaTable . AddCredential ( & internalpb . CredentialInfo { Username : util . UserRoot , EncryptedPassword : encryptedRootPassword } )
return err
}
return nil
}
2022-08-04 03:04:34 +00:00
func ( c * Core ) initRbac ( ) ( initError error ) {
// create default roles, including admin, public
2022-08-23 02:26:53 +00:00
for _ , role := range util . DefaultRoles {
if initError = c . MetaTable . CreateRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : role } ) ; initError != nil {
if common . IsIgnorableError ( initError ) {
initError = nil
continue
}
return
}
2022-08-04 03:04:34 +00:00
}
// grant privileges for the public role
globalPrivileges := [ ] string {
commonpb . ObjectPrivilege_PrivilegeDescribeCollection . String ( ) ,
commonpb . ObjectPrivilege_PrivilegeShowCollections . String ( ) ,
}
2022-08-05 08:28:35 +00:00
collectionPrivileges := [ ] string {
commonpb . ObjectPrivilege_PrivilegeIndexDetail . String ( ) ,
}
2022-08-04 03:04:34 +00:00
for _ , globalPrivilege := range globalPrivileges {
if initError = c . MetaTable . OperatePrivilege ( util . DefaultTenant , & milvuspb . GrantEntity {
Role : & milvuspb . RoleEntity { Name : util . RolePublic } ,
Object : & milvuspb . ObjectEntity { Name : commonpb . ObjectType_Global . String ( ) } ,
2022-08-15 08:40:48 +00:00
ObjectName : util . AnyWord ,
2022-08-04 03:04:34 +00:00
Grantor : & milvuspb . GrantorEntity {
User : & milvuspb . UserEntity { Name : util . RoleAdmin } ,
Privilege : & milvuspb . PrivilegeEntity { Name : globalPrivilege } ,
} ,
} , milvuspb . OperatePrivilegeType_Grant ) ; initError != nil {
2022-08-23 02:26:53 +00:00
if common . IsIgnorableError ( initError ) {
initError = nil
continue
}
2022-08-04 03:04:34 +00:00
return
}
}
2022-08-05 08:28:35 +00:00
for _ , collectionPrivilege := range collectionPrivileges {
if initError = c . MetaTable . OperatePrivilege ( util . DefaultTenant , & milvuspb . GrantEntity {
Role : & milvuspb . RoleEntity { Name : util . RolePublic } ,
Object : & milvuspb . ObjectEntity { Name : commonpb . ObjectType_Collection . String ( ) } ,
2022-08-15 08:40:48 +00:00
ObjectName : util . AnyWord ,
2022-08-05 08:28:35 +00:00
Grantor : & milvuspb . GrantorEntity {
User : & milvuspb . UserEntity { Name : util . RoleAdmin } ,
Privilege : & milvuspb . PrivilegeEntity { Name : collectionPrivilege } ,
} ,
} , milvuspb . OperatePrivilegeType_Grant ) ; initError != nil {
2022-08-23 02:26:53 +00:00
if common . IsIgnorableError ( initError ) {
initError = nil
continue
}
2022-08-05 08:28:35 +00:00
return
}
}
2022-08-04 03:04:34 +00:00
return nil
}
2022-06-14 08:18:09 +00:00
func ( c * Core ) getCollectionName ( collID , partitionID typeutil . UniqueID ) ( string , string , error ) {
colName , err := c . MetaTable . GetCollectionNameByID ( collID )
if err != nil {
log . Error ( "RootCoord failed to get collection name by id" , zap . Int64 ( "ID" , collID ) , zap . Error ( err ) )
return "" , "" , err
}
partName , err := c . MetaTable . GetPartitionNameByID ( collID , partitionID , 0 )
if err != nil {
log . Error ( "RootCoord failed to get partition name by id" , zap . Int64 ( "ID" , partitionID ) , zap . Error ( err ) )
return colName , "" , err
}
return colName , partName , nil
}
2022-04-03 03:37:29 +00:00
// Start starts RootCoord.
2021-01-19 06:44:03 +00:00
func ( c * Core ) Start ( ) error {
if err := c . checkInit ( ) ; err != nil {
2021-06-17 08:47:57 +00:00
log . Debug ( "RootCoord Start checkInit failed" , zap . Error ( err ) )
2021-01-19 06:44:03 +00:00
return err
}
2021-04-08 09:31:39 +00:00
2022-06-15 04:20:10 +00:00
log . Debug ( "starting service" ,
zap . String ( "service role" , typeutil . RootCoordRole ) ,
zap . Int64 ( "node id" , c . session . ServerID ) )
2021-04-08 09:31:39 +00:00
2021-01-19 06:44:03 +00:00
c . startOnce . Do ( func ( ) {
2021-06-22 11:08:03 +00:00
if err := c . proxyManager . WatchProxy ( ) ; err != nil {
2021-10-27 14:00:27 +00:00
log . Fatal ( "RootCoord Start WatchProxy failed" , zap . Error ( err ) )
// you can not just stuck here,
panic ( err )
2021-05-26 12:14:30 +00:00
}
2022-06-17 10:08:12 +00:00
c . wg . Add ( 7 )
2021-01-19 06:44:03 +00:00
go c . startTimeTickLoop ( )
2021-01-27 08:38:18 +00:00
go c . tsLoop ( )
2021-11-25 02:07:15 +00:00
go c . chanTimeTick . startWatch ( & c . wg )
2021-07-03 09:54:25 +00:00
go c . checkFlushedSegmentsLoop ( )
2022-06-15 04:20:10 +00:00
go c . importManager . expireOldTasksLoop ( & c . wg , c . CallReleaseSegRefLock )
2022-05-07 06:05:52 +00:00
go c . importManager . sendOutTasksLoop ( & c . wg )
2022-06-17 10:08:12 +00:00
go c . recycleDroppedIndex ( )
2021-12-23 10:39:11 +00:00
Params . RootCoordCfg . CreatedTime = time . Now ( )
Params . RootCoordCfg . UpdatedTime = time . Now ( )
2021-01-19 06:44:03 +00:00
} )
2021-09-17 13:52:00 +00:00
2021-01-19 06:44:03 +00:00
return nil
}
2022-04-03 03:37:29 +00:00
// Stop stops rootCoord.
2021-01-19 06:44:03 +00:00
func ( c * Core ) Stop ( ) error {
2021-12-07 10:39:03 +00:00
c . UpdateStateCode ( internalpb . StateCode_Abnormal )
2021-01-19 06:44:03 +00:00
c . cancel ( )
2021-09-17 04:37:50 +00:00
c . wg . Wait ( )
2021-11-16 14:31:14 +00:00
// wait at most one second to revoke
c . session . Revoke ( time . Second )
2021-01-19 06:44:03 +00:00
return nil
}
2021-09-23 07:10:00 +00:00
// GetComponentStates get states of components
2021-03-12 06:22:09 +00:00
func ( c * Core ) GetComponentStates ( ctx context . Context ) ( * internalpb . ComponentStates , error ) {
code := c . stateCode . Load ( ) . ( internalpb . StateCode )
log . Debug ( "GetComponentStates" , zap . String ( "State Code" , internalpb . StateCode_name [ int32 ( code ) ] ) )
2021-01-26 11:24:09 +00:00
2021-11-19 05:57:12 +00:00
nodeID := common . NotRegisteredID
if c . session != nil && c . session . Registered ( ) {
nodeID = c . session . ServerID
}
2021-03-12 06:22:09 +00:00
return & internalpb . ComponentStates {
State : & internalpb . ComponentInfo {
2021-11-19 05:57:12 +00:00
// NodeID: c.session.ServerID, // will race with Core.Register()
NodeID : nodeID ,
2021-06-17 08:47:57 +00:00
Role : typeutil . RootCoordRole ,
2021-01-20 03:02:29 +00:00
StateCode : code ,
ExtraInfo : nil ,
2021-01-19 06:44:03 +00:00
} ,
2021-01-26 09:47:38 +00:00
Status : & commonpb . Status {
2021-03-10 14:06:22 +00:00
ErrorCode : commonpb . ErrorCode_Success ,
2021-01-26 09:47:38 +00:00
Reason : "" ,
} ,
2021-03-12 06:22:09 +00:00
SubcomponentStates : [ ] * internalpb . ComponentInfo {
2021-01-26 09:47:38 +00:00
{
2021-11-19 05:57:12 +00:00
NodeID : nodeID ,
2021-06-17 08:47:57 +00:00
Role : typeutil . RootCoordRole ,
2021-01-26 09:47:38 +00:00
StateCode : code ,
ExtraInfo : nil ,
} ,
} ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-09-23 07:10:00 +00:00
// GetTimeTickChannel get timetick channel name
2021-02-26 09:44:24 +00:00
func ( c * Core ) GetTimeTickChannel ( ctx context . Context ) ( * milvuspb . StringResponse , error ) {
return & milvuspb . StringResponse {
Status : & commonpb . Status {
2021-03-10 14:06:22 +00:00
ErrorCode : commonpb . ErrorCode_Success ,
2021-02-26 09:44:24 +00:00
Reason : "" ,
} ,
2022-03-04 03:17:56 +00:00
Value : Params . CommonCfg . RootCoordTimeTick ,
2021-02-26 09:44:24 +00:00
} , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// GetStatisticsChannel get statistics channel name
2021-02-26 09:44:24 +00:00
func ( c * Core ) GetStatisticsChannel ( ctx context . Context ) ( * milvuspb . StringResponse , error ) {
return & milvuspb . StringResponse {
Status : & commonpb . Status {
2021-03-10 14:06:22 +00:00
ErrorCode : commonpb . ErrorCode_Success ,
2021-02-26 09:44:24 +00:00
Reason : "" ,
} ,
2022-03-04 03:17:56 +00:00
Value : Params . CommonCfg . RootCoordStatistics ,
2021-02-26 09:44:24 +00:00
} , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// CreateCollection create collection
2021-02-26 09:44:24 +00:00
func ( c * Core ) CreateCollection ( ctx context . Context , in * milvuspb . CreateCollectionRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateCollection" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-01-25 10:33:10 +00:00
}
2021-11-19 04:11:12 +00:00
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "CreateCollection" )
2021-12-13 01:59:27 +00:00
log . Debug ( "CreateCollection" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & CreateCollectionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "CreateCollection failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateCollection" , metrics . FailLabel ) . Inc ( )
2021-11-22 08:01:14 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "CreateCollection failed: " + err . Error ( ) ) , nil
2021-01-19 06:44:03 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "CreateCollection success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateCollection" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "CreateCollection" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-03-02 13:11:57 +00:00
metrics . RootCoordNumOfCollections . Inc ( )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// DropCollection drop collection
2021-02-26 09:44:24 +00:00
func ( c * Core ) DropCollection ( ctx context . Context , in * milvuspb . DropCollectionRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropCollection" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-01-25 10:33:10 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DropCollection" )
2021-12-13 01:59:27 +00:00
log . Debug ( "DropCollection" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & DropCollectionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "DropCollection failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropCollection" , metrics . FailLabel ) . Inc ( )
2021-11-22 08:01:14 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "DropCollection failed: " + err . Error ( ) ) , nil
2021-01-19 06:44:03 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "DropCollection success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropCollection" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DropCollection" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-03-02 13:11:57 +00:00
metrics . RootCoordNumOfCollections . Dec ( )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// HasCollection check collection existence
2021-02-26 09:44:24 +00:00
func ( c * Core ) HasCollection ( ctx context . Context , in * milvuspb . HasCollectionRequest ) ( * milvuspb . BoolResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "HasCollection" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-01-25 10:33:10 +00:00
return & milvuspb . BoolResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
Value : false ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "HasCollection" )
2021-11-19 04:11:12 +00:00
2021-12-13 01:59:27 +00:00
log . Debug ( "HasCollection" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & HasCollectionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
HasCollection : false ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "HasCollection failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "HasCollection" , metrics . FailLabel ) . Inc ( )
2021-01-19 06:44:03 +00:00
return & milvuspb . BoolResponse {
2021-11-22 08:01:14 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "HasCollection failed: " + err . Error ( ) ) ,
2021-11-19 04:11:12 +00:00
Value : false ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "HasCollection success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-27 02:01:47 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Bool ( "hasCollection" , t . HasCollection ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "HasCollection" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "HasCollection" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-01-19 06:44:03 +00:00
return & milvuspb . BoolResponse {
2021-11-19 04:11:12 +00:00
Status : succStatus ( ) ,
Value : t . HasCollection ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-09-23 07:10:00 +00:00
// DescribeCollection return collection info
2021-02-26 09:44:24 +00:00
func ( c * Core ) DescribeCollection ( ctx context . Context , in * milvuspb . DescribeCollectionRequest ) ( * milvuspb . DescribeCollectionResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeCollection" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-01-25 10:33:10 +00:00
return & milvuspb . DescribeCollectionResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DescribeCollection" )
2021-11-19 04:11:12 +00:00
2022-08-23 02:44:52 +00:00
log . Ctx ( ctx ) . Debug ( "DescribeCollection" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-06-09 13:04:07 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "id" , in . CollectionID ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & DescribeCollectionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
Rsp : & milvuspb . DescribeCollectionResponse { } ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2022-08-23 02:44:52 +00:00
log . Ctx ( ctx ) . Warn ( "DescribeCollection failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-06-09 13:04:07 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "id" , in . CollectionID ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeCollection" , metrics . FailLabel ) . Inc ( )
2021-01-19 06:44:03 +00:00
return & milvuspb . DescribeCollectionResponse {
2021-11-22 08:01:14 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "DescribeCollection failed: " + err . Error ( ) ) ,
2021-01-19 06:44:03 +00:00
} , nil
}
2022-08-23 02:44:52 +00:00
log . Ctx ( ctx ) . Debug ( "DescribeCollection success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-06-09 13:04:07 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "id" , in . CollectionID ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeCollection" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DescribeCollection" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
t . Rsp . Status = succStatus ( )
2021-01-19 06:44:03 +00:00
return t . Rsp , nil
}
2021-09-23 07:10:00 +00:00
// ShowCollections list all collection names
2021-03-12 06:22:09 +00:00
func ( c * Core ) ShowCollections ( ctx context . Context , in * milvuspb . ShowCollectionsRequest ) ( * milvuspb . ShowCollectionsResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowCollections" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-03-12 06:22:09 +00:00
return & milvuspb . ShowCollectionsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "ShowCollections" )
2021-11-19 04:11:12 +00:00
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowCollections" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "dbname" , in . DbName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & ShowCollectionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
2021-11-19 04:11:12 +00:00
Rsp : & milvuspb . ShowCollectionsResponse { } ,
2021-01-19 06:44:03 +00:00
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "ShowCollections failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "dbname" , in . DbName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowCollections" , metrics . FailLabel ) . Inc ( )
2021-03-12 06:22:09 +00:00
return & milvuspb . ShowCollectionsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "ShowCollections failed: " + err . Error ( ) ) ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowCollections success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "dbname" , in . DbName ) , zap . Int ( "num of collections" , len ( t . Rsp . CollectionNames ) ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowCollections" , metrics . SuccessLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
t . Rsp . Status = succStatus ( )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqLatency . WithLabelValues ( "ShowCollections" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-01-19 06:44:03 +00:00
return t . Rsp , nil
}
2021-09-23 07:10:00 +00:00
// CreatePartition create partition
2021-02-26 09:44:24 +00:00
func ( c * Core ) CreatePartition ( ctx context . Context , in * milvuspb . CreatePartitionRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreatePartition" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-01-25 10:33:10 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "CreatePartition" )
2021-12-13 01:59:27 +00:00
log . Debug ( "CreatePartition" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & CreatePartitionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "CreatePartition failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreatePartition" , metrics . FailLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "CreatePartition failed: " + err . Error ( ) ) , nil
2021-01-19 06:44:03 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "CreatePartition success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreatePartition" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "CreatePartition" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-26 09:29:45 +00:00
metrics . RootCoordNumOfPartitions . WithLabelValues ( ) . Inc ( )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// DropPartition drop partition
2021-02-26 09:44:24 +00:00
func ( c * Core ) DropPartition ( ctx context . Context , in * milvuspb . DropPartitionRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropPartition" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-01-25 10:33:10 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DropPartition" )
2021-12-13 01:59:27 +00:00
log . Debug ( "DropPartition" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & DropPartitionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "DropPartition failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropPartition" , metrics . FailLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "DropPartition failed: " + err . Error ( ) ) , nil
2021-01-19 06:44:03 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "DropPartition success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropPartition" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DropPartition" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-26 09:29:45 +00:00
metrics . RootCoordNumOfPartitions . WithLabelValues ( ) . Dec ( )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// HasPartition check partition existence
2021-02-26 09:44:24 +00:00
func ( c * Core ) HasPartition ( ctx context . Context , in * milvuspb . HasPartitionRequest ) ( * milvuspb . BoolResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "HasPartition" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-01-25 10:33:10 +00:00
return & milvuspb . BoolResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
Value : false ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "HasPartition" )
2021-11-19 04:11:12 +00:00
2021-12-13 01:59:27 +00:00
log . Debug ( "HasPartition" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & HasPartitionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
HasPartition : false ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "HasPartition failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "HasPartition" , metrics . FailLabel ) . Inc ( )
2021-01-19 06:44:03 +00:00
return & milvuspb . BoolResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "HasPartition failed: " + err . Error ( ) ) ,
Value : false ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "HasPartition success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "partition name" , in . PartitionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "HasPartition" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "HasPartition" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-01-19 06:44:03 +00:00
return & milvuspb . BoolResponse {
2021-11-19 04:11:12 +00:00
Status : succStatus ( ) ,
Value : t . HasPartition ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-09-23 07:10:00 +00:00
// ShowPartitions list all partition names
2021-03-12 06:22:09 +00:00
func ( c * Core ) ShowPartitions ( ctx context . Context , in * milvuspb . ShowPartitionsRequest ) ( * milvuspb . ShowPartitionsResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowPartitions" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-03-12 06:22:09 +00:00
return & milvuspb . ShowPartitionsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-01-25 10:33:10 +00:00
} , nil
}
2021-11-19 04:11:12 +00:00
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "ShowPartitions" )
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowPartitions" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-19 06:44:03 +00:00
t := & ShowPartitionReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-19 06:44:03 +00:00
core : c ,
} ,
Req : in ,
2021-11-19 04:11:12 +00:00
Rsp : & milvuspb . ShowPartitionsResponse { } ,
2021-01-19 06:44:03 +00:00
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "ShowPartitions failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowPartitions" , metrics . FailLabel ) . Inc ( )
2021-03-12 06:22:09 +00:00
return & milvuspb . ShowPartitionsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "ShowPartitions failed: " + err . Error ( ) ) ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowPartitions success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . Int ( "num of partitions" , len ( t . Rsp . PartitionNames ) ) ,
zap . Int64 ( "msgID" , t . Req . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowPartitions" , metrics . SuccessLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
t . Rsp . Status = succStatus ( )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqLatency . WithLabelValues ( "ShowPartitions" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-01-19 06:44:03 +00:00
return t . Rsp , nil
}
2021-09-23 07:10:00 +00:00
// CreateIndex create index
2021-02-26 09:44:24 +00:00
func ( c * Core ) CreateIndex ( ctx context . Context , in * milvuspb . CreateIndexRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateIndex" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-01-25 10:33:10 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "CreateIndex" )
2021-12-13 01:59:27 +00:00
log . Debug ( "CreateIndex" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-21 02:01:29 +00:00
t := & CreateIndexReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-21 02:01:29 +00:00
core : c ,
} ,
Req : in ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-21 02:01:29 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "CreateIndex failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateIndex" , metrics . FailLabel ) . Inc ( )
2021-11-22 08:01:14 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "CreateIndex failed: " + err . Error ( ) ) , nil
2021-01-21 02:01:29 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "CreateIndex success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateIndex" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "CreateIndex" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// DescribeIndex return index info
2021-02-26 09:44:24 +00:00
func ( c * Core ) DescribeIndex ( ctx context . Context , in * milvuspb . DescribeIndexRequest ) ( * milvuspb . DescribeIndexResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeIndex" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-01-25 10:33:10 +00:00
return & milvuspb . DescribeIndexResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DescribeIndex" )
2021-12-13 01:59:27 +00:00
log . Debug ( "DescribeIndex" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-21 02:01:29 +00:00
t := & DescribeIndexReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-21 02:01:29 +00:00
core : c ,
} ,
Req : in ,
2021-11-19 04:11:12 +00:00
Rsp : & milvuspb . DescribeIndexResponse { } ,
2021-01-21 02:01:29 +00:00
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-21 02:01:29 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "DescribeIndex failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeIndex" , metrics . FailLabel ) . Inc ( )
2021-01-21 02:01:29 +00:00
return & milvuspb . DescribeIndexResponse {
2021-11-22 08:01:14 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "DescribeIndex failed: " + err . Error ( ) ) ,
2021-01-21 02:01:29 +00:00
} , nil
}
2021-02-24 08:25:40 +00:00
idxNames := make ( [ ] string , 0 , len ( t . Rsp . IndexDescriptions ) )
for _ , i := range t . Rsp . IndexDescriptions {
idxNames = append ( idxNames , i . IndexName )
}
2021-12-13 01:59:27 +00:00
log . Debug ( "DescribeIndex success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . Strings ( "index names" , idxNames ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeIndex" , metrics . SuccessLabel ) . Inc ( )
2021-03-05 12:41:34 +00:00
if len ( t . Rsp . IndexDescriptions ) == 0 {
2021-11-22 08:01:14 +00:00
t . Rsp . Status = failStatus ( commonpb . ErrorCode_IndexNotExist , "index not exist" )
2021-03-05 12:41:34 +00:00
} else {
2021-11-19 04:11:12 +00:00
t . Rsp . Status = succStatus ( )
2021-01-21 02:01:29 +00:00
}
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DescribeIndex" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-01-21 02:01:29 +00:00
return t . Rsp , nil
2021-01-19 06:44:03 +00:00
}
2022-06-16 12:12:11 +00:00
func ( c * Core ) GetIndexState ( ctx context . Context , in * milvuspb . GetIndexStateRequest ) ( * indexpb . GetIndexStatesResponse , error ) {
if code , ok := c . checkHealthy ( ) ; ! ok {
log . Error ( "RootCoord GetIndexState failed, RootCoord is not healthy" )
return & indexpb . GetIndexStatesResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
} , nil
}
log . Info ( "RootCoord GetIndexState" , zap . String ( "collName" , in . GetCollectionName ( ) ) ,
zap . String ( "fieldName" , in . GetFieldName ( ) ) , zap . String ( "indexName" , in . GetIndexName ( ) ) )
// initBuildIDs are the buildIDs generated when CreateIndex is called.
initBuildIDs , err := c . MetaTable . GetInitBuildIDs ( in . GetCollectionName ( ) , in . GetIndexName ( ) )
if err != nil {
log . Error ( "RootCoord GetIndexState failed" , zap . String ( "collName" , in . GetCollectionName ( ) ) ,
zap . String ( "fieldName" , in . GetFieldName ( ) ) , zap . String ( "indexName" , in . GetIndexName ( ) ) , zap . Error ( err ) )
return & indexpb . GetIndexStatesResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) ) ,
} , nil
}
ret := & indexpb . GetIndexStatesResponse {
Status : succStatus ( ) ,
}
if len ( initBuildIDs ) == 0 {
log . Warn ( "RootCoord GetIndexState successful, all segments generated when CreateIndex is called have been compacted" )
return ret , nil
}
states , err := c . CallGetIndexStatesService ( ctx , initBuildIDs )
if err != nil {
log . Error ( "RootCoord GetIndexState CallGetIndexStatesService failed" , zap . String ( "collName" , in . GetCollectionName ( ) ) ,
zap . String ( "fieldName" , in . GetFieldName ( ) ) , zap . String ( "indexName" , in . GetIndexName ( ) ) , zap . Error ( err ) )
ret . Status = failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) )
return ret , err
}
log . Info ( "RootCoord GetIndexState successful" , zap . String ( "collName" , in . GetCollectionName ( ) ) ,
zap . String ( "fieldName" , in . GetFieldName ( ) ) , zap . String ( "indexName" , in . GetIndexName ( ) ) )
return & indexpb . GetIndexStatesResponse {
Status : succStatus ( ) ,
States : states ,
} , nil
}
2021-09-23 07:10:00 +00:00
// DropIndex drop index
2021-02-26 09:44:24 +00:00
func ( c * Core ) DropIndex ( ctx context . Context , in * milvuspb . DropIndexRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropIndex" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-02-20 07:38:44 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DropIndex" )
2021-12-13 01:59:27 +00:00
log . Debug ( "DropIndex" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . String ( "index name" , in . IndexName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-02-20 07:38:44 +00:00
t := & DropIndexReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-02-20 07:38:44 +00:00
core : c ,
} ,
Req : in ,
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-02-20 07:38:44 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "DropIndex failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . String ( "index name" , in . IndexName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropIndex" , metrics . FailLabel ) . Inc ( )
2021-11-22 08:01:14 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "DropIndex failed: " + err . Error ( ) ) , nil
2021-02-20 07:38:44 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "DropIndex success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "collection name" , in . CollectionName ) , zap . String ( "field name" , in . FieldName ) ,
zap . String ( "index name" , in . IndexName ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropIndex" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DropIndex" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-02-20 07:38:44 +00:00
}
2021-09-23 07:10:00 +00:00
// DescribeSegment return segment info
2021-02-26 09:44:24 +00:00
func ( c * Core ) DescribeSegment ( ctx context . Context , in * milvuspb . DescribeSegmentRequest ) ( * milvuspb . DescribeSegmentResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeSegment" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-01-25 10:33:10 +00:00
return & milvuspb . DescribeSegmentResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DescribeSegment" )
2021-12-13 01:59:27 +00:00
log . Debug ( "DescribeSegment" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . CollectionID ) , zap . Int64 ( "segment id" , in . SegmentID ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-21 02:01:29 +00:00
t := & DescribeSegmentReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-21 02:01:29 +00:00
core : c ,
} ,
Req : in ,
2021-11-19 04:11:12 +00:00
Rsp : & milvuspb . DescribeSegmentResponse { } ,
2021-01-21 02:01:29 +00:00
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-21 02:01:29 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "DescribeSegment failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . CollectionID ) , zap . Int64 ( "segment id" , in . SegmentID ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeSegment" , metrics . FailLabel ) . Inc ( )
2021-01-21 02:01:29 +00:00
return & milvuspb . DescribeSegmentResponse {
2021-11-22 08:01:14 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "DescribeSegment failed: " + err . Error ( ) ) ,
2021-01-21 02:01:29 +00:00
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "DescribeSegment success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . CollectionID ) , zap . Int64 ( "segment id" , in . SegmentID ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeSegment" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DescribeSegment" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
t . Rsp . Status = succStatus ( )
2021-01-21 02:01:29 +00:00
return t . Rsp , nil
2021-01-19 06:44:03 +00:00
}
2022-03-30 13:11:28 +00:00
func ( c * Core ) DescribeSegments ( ctx context . Context , in * rootcoordpb . DescribeSegmentsRequest ) ( * rootcoordpb . DescribeSegmentsResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeSegments" , metrics . TotalLabel ) . Inc ( )
2022-03-30 13:11:28 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
log . Error ( "failed to describe segments, rootcoord not healthy" ,
zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) ,
zap . Int64 ( "collection" , in . GetCollectionID ( ) ) ,
zap . Int64s ( "segments" , in . GetSegmentIDs ( ) ) )
return & rootcoordpb . DescribeSegmentsResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
} , nil
}
tr := timerecord . NewTimeRecorder ( "DescribeSegments" )
log . Debug ( "received request to describe segments" ,
zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) ,
zap . Int64 ( "collection" , in . GetCollectionID ( ) ) ,
zap . Int64s ( "segments" , in . GetSegmentIDs ( ) ) )
t := & DescribeSegmentsReqTask {
baseReqTask : baseReqTask {
ctx : ctx ,
core : c ,
} ,
Req : in ,
Rsp : & rootcoordpb . DescribeSegmentsResponse { } ,
}
if err := executeTask ( t ) ; err != nil {
log . Error ( "failed to describe segments" ,
zap . Error ( err ) ,
zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) ,
zap . Int64 ( "collection" , in . GetCollectionID ( ) ) ,
zap . Int64s ( "segments" , in . GetSegmentIDs ( ) ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeSegments" , metrics . FailLabel ) . Inc ( )
2022-03-30 13:11:28 +00:00
return & rootcoordpb . DescribeSegmentsResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "DescribeSegments failed: " + err . Error ( ) ) ,
} , nil
}
log . Debug ( "succeed to describe segments" ,
zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) ,
zap . Int64 ( "collection" , in . GetCollectionID ( ) ) ,
zap . Int64s ( "segments" , in . GetSegmentIDs ( ) ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DescribeSegments" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DescribeSegments" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-03-30 13:11:28 +00:00
t . Rsp . Status = succStatus ( )
return t . Rsp , nil
}
2021-09-23 07:10:00 +00:00
// ShowSegments list all segments
2021-03-12 06:22:09 +00:00
func ( c * Core ) ShowSegments ( ctx context . Context , in * milvuspb . ShowSegmentsRequest ) ( * milvuspb . ShowSegmentsResponse , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowSegments" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-03-12 06:22:09 +00:00
return & milvuspb . ShowSegmentsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-01-25 10:33:10 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "ShowSegments" )
2021-11-19 04:11:12 +00:00
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowSegments" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . CollectionID ) , zap . Int64 ( "partition id" , in . PartitionID ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-01-21 02:01:29 +00:00
t := & ShowSegmentReqTask {
baseReqTask : baseReqTask {
2021-03-13 06:42:53 +00:00
ctx : ctx ,
2021-01-21 02:01:29 +00:00
core : c ,
} ,
Req : in ,
2021-11-19 04:11:12 +00:00
Rsp : & milvuspb . ShowSegmentsResponse { } ,
2021-01-21 02:01:29 +00:00
}
2021-06-26 01:22:11 +00:00
err := executeTask ( t )
2021-01-21 02:01:29 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowSegments failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . CollectionID ) , zap . Int64 ( "partition id" , in . PartitionID ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowSegments" , metrics . FailLabel ) . Inc ( )
2021-03-12 06:22:09 +00:00
return & milvuspb . ShowSegmentsResponse {
2021-11-22 08:01:14 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "ShowSegments failed: " + err . Error ( ) ) ,
2021-01-21 02:01:29 +00:00
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "ShowSegments success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . CollectionID ) , zap . Int64 ( "partition id" , in . PartitionID ) ,
zap . Int64s ( "segments ids" , t . Rsp . SegmentIDs ) ,
2021-11-19 04:11:12 +00:00
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "ShowSegments" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "ShowSegments" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
t . Rsp . Status = succStatus ( )
2021-01-21 02:01:29 +00:00
return t . Rsp , nil
2021-01-19 06:44:03 +00:00
}
2021-09-23 07:10:00 +00:00
// AllocTimestamp alloc timestamp
2021-06-22 08:14:09 +00:00
func ( c * Core ) AllocTimestamp ( ctx context . Context , in * rootcoordpb . AllocTimestampRequest ) ( * rootcoordpb . AllocTimestampResponse , error ) {
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-06-22 08:14:09 +00:00
return & rootcoordpb . AllocTimestampResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-05-26 12:14:30 +00:00
} , nil
}
2021-05-20 06:14:14 +00:00
ts , err := c . TSOAllocator ( in . Count )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "AllocTimestamp failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2021-06-22 08:14:09 +00:00
return & rootcoordpb . AllocTimestampResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "AllocTimestamp failed: " + err . Error ( ) ) ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-07-14 09:11:54 +00:00
//return first available time stamp
ts = ts - uint64 ( in . Count ) + 1
2022-04-27 15:03:47 +00:00
metrics . RootCoordTimestamp . Set ( float64 ( ts ) )
2021-06-22 08:14:09 +00:00
return & rootcoordpb . AllocTimestampResponse {
2021-11-19 04:11:12 +00:00
Status : succStatus ( ) ,
2021-01-19 06:44:03 +00:00
Timestamp : ts ,
Count : in . Count ,
} , nil
}
2021-09-23 07:10:00 +00:00
// AllocID alloc ids
2021-06-22 08:14:09 +00:00
func ( c * Core ) AllocID ( ctx context . Context , in * rootcoordpb . AllocIDRequest ) ( * rootcoordpb . AllocIDResponse , error ) {
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-06-22 08:14:09 +00:00
return & rootcoordpb . AllocIDResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-05-26 12:14:30 +00:00
} , nil
}
2021-05-20 06:14:14 +00:00
start , _ , err := c . IDAllocator ( in . Count )
2021-01-19 06:44:03 +00:00
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "AllocID failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2021-06-22 08:14:09 +00:00
return & rootcoordpb . AllocIDResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "AllocID failed: " + err . Error ( ) ) ,
Count : in . Count ,
2021-01-19 06:44:03 +00:00
} , nil
}
2022-03-02 13:11:57 +00:00
metrics . RootCoordIDAllocCounter . Add ( float64 ( in . Count ) )
2021-06-22 08:14:09 +00:00
return & rootcoordpb . AllocIDResponse {
2021-11-19 04:11:12 +00:00
Status : succStatus ( ) ,
ID : start ,
Count : in . Count ,
2021-01-19 06:44:03 +00:00
} , nil
}
2021-05-21 08:08:12 +00:00
// UpdateChannelTimeTick used to handle ChannelTimeTickMsg
func ( c * Core ) UpdateChannelTimeTick ( ctx context . Context , in * internalpb . ChannelTimeTickMsg ) ( * commonpb . Status , error ) {
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
2022-01-15 10:53:34 +00:00
log . Warn ( "failed to updateTimeTick because rootcoord is not healthy" , zap . Any ( "state" , code ) )
2021-11-19 04:11:12 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-05-21 08:08:12 +00:00
}
if in . Base . MsgType != commonpb . MsgType_TimeTick {
2022-01-15 10:53:34 +00:00
log . Warn ( "failed to updateTimeTick because base messasge is not timetick, state" , zap . Any ( "base message type" , in . Base . MsgType ) )
2021-11-19 04:11:12 +00:00
msgTypeName := commonpb . MsgType_name [ int32 ( in . Base . GetMsgType ( ) ) ]
return failStatus ( commonpb . ErrorCode_UnexpectedError , "invalid message type " + msgTypeName ) , nil
2021-05-21 08:08:12 +00:00
}
2021-11-25 02:07:15 +00:00
err := c . chanTimeTick . updateTimeTick ( in , "gRPC" )
2021-05-21 08:08:12 +00:00
if err != nil {
2022-01-15 10:53:34 +00:00
log . Warn ( "failed to updateTimeTick" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2021-11-19 04:11:12 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "UpdateTimeTick failed: " + err . Error ( ) ) , nil
2021-05-21 08:08:12 +00:00
}
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-05-21 08:08:12 +00:00
}
2021-06-17 09:45:56 +00:00
2021-09-23 07:10:00 +00:00
// ReleaseDQLMessageStream release DQL msgstream
2021-06-17 09:45:56 +00:00
func ( c * Core ) ReleaseDQLMessageStream ( ctx context . Context , in * proxypb . ReleaseDQLMessageStreamRequest ) ( * commonpb . Status , error ) {
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-06-17 09:45:56 +00:00
}
2022-05-19 02:13:56 +00:00
err := c . proxyClientManager . ReleaseDQLMessageStream ( ctx , in )
if err != nil {
return failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) ) , nil
}
return succStatus ( ) , nil
}
// InvalidateCollectionMetaCache notifies RootCoord to release the collection cache in Proxies.
func ( c * Core ) InvalidateCollectionMetaCache ( ctx context . Context , in * proxypb . InvalidateCollMetaCacheRequest ) ( * commonpb . Status , error ) {
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
}
err := c . proxyClientManager . InvalidateCollectionMetaCache ( ctx , in )
if err != nil {
return failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) ) , nil
}
return succStatus ( ) , nil
2021-06-17 09:45:56 +00:00
}
2021-07-01 06:58:17 +00:00
2021-09-23 07:10:00 +00:00
// SegmentFlushCompleted check whether segment flush has completed
2022-06-17 17:24:11 +00:00
func ( c * Core ) SegmentFlushCompleted ( ctx context . Context , in * datapb . SegmentFlushCompletedMsg ) ( status * commonpb . Status , err error ) {
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-07-01 06:58:17 +00:00
}
if in . Base . MsgType != commonpb . MsgType_SegmentFlushDone {
2021-11-22 08:01:14 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "invalid msg type " + commonpb . MsgType_name [ int32 ( in . Base . MsgType ) ] ) , nil
2021-07-01 06:58:17 +00:00
}
2022-06-17 10:08:12 +00:00
log . Info ( "SegmentFlushCompleted received" , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Int64 ( "collID" , in . Segment . CollectionID ) ,
zap . Int64 ( "partID" , in . Segment . PartitionID ) , zap . Int64 ( "segID" , in . Segment . ID ) , zap . Int64s ( "compactFrom" , in . Segment . CompactionFrom ) )
2022-06-17 17:24:11 +00:00
err = c . createIndexForSegment ( ctx , in . Segment . CollectionID , in . Segment . PartitionID , in . Segment . ID , in . Segment . NumOfRows , in . Segment . Binlogs )
2021-07-01 06:58:17 +00:00
if err != nil {
2022-06-17 10:08:12 +00:00
log . Error ( "createIndexForSegment" , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Int64 ( "collID" , in . Segment . CollectionID ) ,
zap . Int64 ( "partID" , in . Segment . PartitionID ) , zap . Int64 ( "segID" , in . Segment . ID ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) ) , nil
2021-07-01 06:58:17 +00:00
}
2022-06-17 10:08:12 +00:00
buildIDs := c . MetaTable . GetBuildIDsBySegIDs ( in . Segment . CompactionFrom )
if len ( buildIDs ) != 0 {
if err = c . CallRemoveIndexService ( ctx , buildIDs ) ; err != nil {
log . Error ( "CallRemoveIndexService failed" , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Int64 ( "collID" , in . Segment . CollectionID ) ,
zap . Int64 ( "partID" , in . Segment . PartitionID ) , zap . Int64 ( "segID" , in . Segment . ID ) ,
zap . Int64s ( "compactFrom" , in . Segment . CompactionFrom ) , zap . Int64s ( "buildIDs" , buildIDs ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) ) , nil
2021-07-01 06:58:17 +00:00
}
}
2022-06-17 10:08:12 +00:00
if err = c . MetaTable . RemoveSegments ( in . Segment . CollectionID , in . Segment . PartitionID , in . Segment . CompactionFrom ) ; err != nil {
log . Error ( "RemoveSegments failed" , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Int64 ( "collID" , in . Segment . CollectionID ) ,
zap . Int64 ( "partID" , in . Segment . PartitionID ) , zap . Int64 ( "segID" , in . Segment . ID ) ,
zap . Int64s ( "compactFrom" , in . Segment . CompactionFrom ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_UnexpectedError , err . Error ( ) ) , nil
}
2022-06-17 17:24:11 +00:00
2021-12-13 01:59:27 +00:00
log . Debug ( "SegmentFlushCompleted success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "collection id" , in . Segment . CollectionID ) , zap . Int64 ( "partition id" , in . Segment . PartitionID ) ,
2022-06-17 10:08:12 +00:00
zap . Int64 ( "segment id" , in . Segment . ID ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-07-01 06:58:17 +00:00
}
2021-08-31 03:45:59 +00:00
2022-08-12 05:20:39 +00:00
//ShowConfigurations returns the configurations of RootCoord matching req.Pattern
func ( c * Core ) ShowConfigurations ( ctx context . Context , req * internalpb . ShowConfigurationsRequest ) ( * internalpb . ShowConfigurationsResponse , error ) {
if code , ok := c . checkHealthy ( ) ; ! ok {
return & internalpb . ShowConfigurationsResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
Configuations : nil ,
} , nil
}
return getComponentConfigurations ( ctx , req ) , nil
}
2021-09-23 07:10:00 +00:00
// GetMetrics get metrics
2021-11-22 08:01:14 +00:00
func ( c * Core ) GetMetrics ( ctx context . Context , in * milvuspb . GetMetricsRequest ) ( * milvuspb . GetMetricsResponse , error ) {
if code , ok := c . checkHealthy ( ) ; ! ok {
2021-08-31 03:45:59 +00:00
return & milvuspb . GetMetricsResponse {
2021-11-22 08:01:14 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
2021-08-31 03:45:59 +00:00
Response : "" ,
} , nil
}
2021-11-22 08:01:14 +00:00
metricType , err := metricsinfo . ParseMetricType ( in . Request )
2021-08-31 03:45:59 +00:00
if err != nil {
2022-07-21 12:52:27 +00:00
log . Warn ( "ParseMetricType failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . Int64 ( "node_id" , c . session . ServerID ) , zap . String ( "req" , in . Request ) , zap . Error ( err ) )
2021-08-31 03:45:59 +00:00
return & milvuspb . GetMetricsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "ParseMetricType failed: " + err . Error ( ) ) ,
2021-08-31 03:45:59 +00:00
Response : "" ,
} , nil
}
2021-12-13 01:59:27 +00:00
log . Debug ( "GetMetrics success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-07-21 12:52:27 +00:00
zap . String ( "metric_type" , metricType ) , zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) )
2021-08-31 03:45:59 +00:00
if metricType == metricsinfo . SystemInfoMetrics {
2021-09-03 09:15:26 +00:00
ret , err := c . metricsCacheManager . GetSystemInfoMetrics ( )
if err == nil && ret != nil {
return ret , nil
}
2021-12-13 01:59:27 +00:00
log . Warn ( "GetSystemInfoMetrics from cache failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-07-21 12:52:27 +00:00
zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) , zap . Error ( err ) )
2021-08-31 03:45:59 +00:00
2021-11-22 08:01:14 +00:00
systemInfoMetrics , err := c . getSystemInfoMetrics ( ctx , in )
if err != nil {
2022-07-21 12:52:27 +00:00
log . Warn ( "GetSystemInfoMetrics failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "metric_type" , metricType ) , zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) , zap . Error ( err ) )
return & milvuspb . GetMetricsResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , fmt . Sprintf ( "getSystemInfoMetrics failed: %s" , err . Error ( ) ) ) ,
Response : "" ,
} , nil
2021-11-22 08:01:14 +00:00
}
2021-08-31 03:45:59 +00:00
2021-09-03 09:15:26 +00:00
c . metricsCacheManager . UpdateSystemInfoMetrics ( systemInfoMetrics )
2021-08-31 03:45:59 +00:00
return systemInfoMetrics , err
}
2022-07-21 12:52:27 +00:00
log . Warn ( "GetMetrics failed, metric type not implemented" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "metric_type" , metricType ) , zap . Int64 ( "msgID" , in . GetBase ( ) . GetMsgID ( ) ) )
2021-08-31 03:45:59 +00:00
return & milvuspb . GetMetricsResponse {
2021-11-19 04:11:12 +00:00
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , metricsinfo . MsgUnimplementedMetric ) ,
2021-08-31 03:45:59 +00:00
Response : "" ,
} , nil
}
2021-09-18 03:13:51 +00:00
2021-09-23 07:10:00 +00:00
// CreateAlias create collection alias
2021-09-18 03:13:51 +00:00
func ( c * Core ) CreateAlias ( ctx context . Context , in * milvuspb . CreateAliasRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateAlias" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-09-18 03:13:51 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "CreateAlias" )
2021-12-13 01:59:27 +00:00
log . Debug ( "CreateAlias" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . String ( "collection name" , in . CollectionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-09-18 03:13:51 +00:00
t := & CreateAliasReqTask {
baseReqTask : baseReqTask {
ctx : ctx ,
core : c ,
} ,
Req : in ,
}
err := executeTask ( t )
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "CreateAlias failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . String ( "collection name" , in . CollectionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateAlias" , metrics . FailLabel ) . Inc ( )
2021-11-22 08:01:14 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "CreateAlias failed: " + err . Error ( ) ) , nil
2021-09-18 03:13:51 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "CreateAlias success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . String ( "collection name" , in . CollectionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "CreateAlias" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "CreateAlias" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-09-18 03:13:51 +00:00
}
2021-09-23 07:10:00 +00:00
// DropAlias drop collection alias
2021-09-18 03:13:51 +00:00
func ( c * Core ) DropAlias ( ctx context . Context , in * milvuspb . DropAliasRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropAlias" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-09-18 03:13:51 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "DropAlias" )
2021-12-13 01:59:27 +00:00
log . Debug ( "DropAlias" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-09-18 03:13:51 +00:00
t := & DropAliasReqTask {
baseReqTask : baseReqTask {
ctx : ctx ,
core : c ,
} ,
Req : in ,
}
err := executeTask ( t )
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "DropAlias failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropAlias" , metrics . FailLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "DropAlias failed: " + err . Error ( ) ) , nil
2021-09-18 03:13:51 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "DropAlias success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropAlias" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "DropAlias" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-09-18 03:13:51 +00:00
}
2021-09-23 07:10:00 +00:00
// AlterAlias alter collection alias
2021-09-18 03:13:51 +00:00
func ( c * Core ) AlterAlias ( ctx context . Context , in * milvuspb . AlterAliasRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "DropAlias" , metrics . TotalLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
2021-09-18 03:13:51 +00:00
}
2022-03-02 13:11:57 +00:00
tr := timerecord . NewTimeRecorder ( "AlterAlias" )
2021-12-13 01:59:27 +00:00
log . Debug ( "AlterAlias" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . String ( "collection name" , in . CollectionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-09-18 03:13:51 +00:00
t := & AlterAliasReqTask {
baseReqTask : baseReqTask {
ctx : ctx ,
core : c ,
} ,
Req : in ,
}
err := executeTask ( t )
if err != nil {
2021-12-13 01:59:27 +00:00
log . Error ( "AlterAlias failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . String ( "collection name" , in . CollectionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "AlterAlias" , metrics . FailLabel ) . Inc ( )
2021-11-19 04:11:12 +00:00
return failStatus ( commonpb . ErrorCode_UnexpectedError , "AlterAlias failed: " + err . Error ( ) ) , nil
2021-09-18 03:13:51 +00:00
}
2021-12-13 01:59:27 +00:00
log . Debug ( "AlterAlias success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2021-11-22 08:01:14 +00:00
zap . String ( "alias" , in . Alias ) , zap . String ( "collection name" , in . CollectionName ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) )
2021-11-19 04:11:12 +00:00
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( "AlterAlias" , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( "AlterAlias" ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2021-11-19 04:11:12 +00:00
return succStatus ( ) , nil
2021-09-18 03:13:51 +00:00
}
2022-03-11 09:13:59 +00:00
2022-03-31 05:51:28 +00:00
// Import imports large files (json, numpy, etc.) on MinIO/S3 storage into Milvus storage.
2022-03-11 09:13:59 +00:00
func ( c * Core ) Import ( ctx context . Context , req * milvuspb . ImportRequest ) ( * milvuspb . ImportResponse , error ) {
2022-03-21 07:47:23 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return & milvuspb . ImportResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
} , nil
2022-03-11 09:13:59 +00:00
}
2022-03-31 05:51:28 +00:00
// Get collection/partition ID from collection/partition name.
2022-05-09 12:47:52 +00:00
var cID UniqueID
2022-04-20 06:03:40 +00:00
var err error
2022-05-09 12:47:52 +00:00
if cID , err = c . MetaTable . GetCollectionIDByName ( req . GetCollectionName ( ) ) ; err != nil {
log . Error ( "failed to find collection ID from its name" ,
zap . String ( "collection name" , req . GetCollectionName ( ) ) ,
zap . Error ( err ) )
return nil , err
}
var pID UniqueID
2022-04-20 06:03:40 +00:00
if pID , err = c . MetaTable . getPartitionByName ( cID , req . GetPartitionName ( ) , 0 ) ; err != nil {
2022-05-09 12:47:52 +00:00
log . Error ( "failed to get partition ID from its name" ,
zap . String ( "partition name" , req . GetPartitionName ( ) ) ,
zap . Error ( err ) )
2022-04-20 06:03:40 +00:00
return nil , err
}
2022-05-31 07:40:04 +00:00
log . Info ( "RootCoord receive import request" ,
2022-03-31 05:51:28 +00:00
zap . String ( "collection name" , req . GetCollectionName ( ) ) ,
zap . Int64 ( "collection ID" , cID ) ,
zap . String ( "partition name" , req . GetPartitionName ( ) ) ,
2022-04-20 06:03:40 +00:00
zap . Int64 ( "partition ID" , pID ) ,
2022-03-31 05:51:28 +00:00
zap . Int ( "# of files = " , len ( req . GetFiles ( ) ) ) ,
2022-04-20 06:03:40 +00:00
zap . Bool ( "row-based" , req . GetRowBased ( ) ) ,
2022-03-31 05:51:28 +00:00
)
2022-04-20 06:03:40 +00:00
resp := c . importManager . importJob ( ctx , req , cID , pID )
2022-03-11 09:13:59 +00:00
return resp , nil
}
2022-04-03 03:37:29 +00:00
// GetImportState returns the current state of an import task.
2022-03-11 09:13:59 +00:00
func ( c * Core ) GetImportState ( ctx context . Context , req * milvuspb . GetImportStateRequest ) ( * milvuspb . GetImportStateResponse , error ) {
2022-03-21 07:47:23 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return & milvuspb . GetImportStateResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
} , nil
}
2022-04-06 07:33:32 +00:00
return c . importManager . getTaskState ( req . GetTask ( ) ) , nil
2022-03-11 09:13:59 +00:00
}
2022-04-25 09:37:46 +00:00
// ListImportTasks returns id array of all import tasks.
func ( c * Core ) ListImportTasks ( ctx context . Context , req * milvuspb . ListImportTasksRequest ) ( * milvuspb . ListImportTasksResponse , error ) {
if code , ok := c . checkHealthy ( ) ; ! ok {
return & milvuspb . ListImportTasksResponse {
Status : failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) ,
} , nil
}
resp := & milvuspb . ListImportTasksResponse {
Status : & commonpb . Status {
ErrorCode : commonpb . ErrorCode_Success ,
} ,
Tasks : c . importManager . listAllTasks ( ) ,
}
return resp , nil
}
2022-03-31 05:51:28 +00:00
// ReportImport reports import task state to RootCoord.
2022-04-01 03:33:28 +00:00
func ( c * Core ) ReportImport ( ctx context . Context , ir * rootcoordpb . ImportResult ) ( * commonpb . Status , error ) {
2022-05-31 07:40:04 +00:00
log . Info ( "RootCoord receive import state report" ,
2022-04-06 07:33:32 +00:00
zap . Int64 ( "task ID" , ir . GetTaskId ( ) ) ,
zap . Any ( "import state" , ir . GetState ( ) ) )
2022-03-21 07:47:23 +00:00
if code , ok := c . checkHealthy ( ) ; ! ok {
return failStatus ( commonpb . ErrorCode_UnexpectedError , "StateCode=" + internalpb . StateCode_name [ int32 ( code ) ] ) , nil
}
2022-06-15 04:20:10 +00:00
// Special case for ImportState_ImportAllocSegment state, where we shall only add segment ref lock and do no other
// operations.
// TODO: This is inelegant and must get re-structured.
if ir . GetState ( ) == commonpb . ImportState_ImportAllocSegment {
// Lock the segments, so we don't lose track of them when compaction happens.
// Note that these locks will be unlocked in c.postImportPersistLoop() -> checkSegmentLoadedLoop().
2022-06-15 13:38:10 +00:00
if err := c . CallAddSegRefLock ( ctx , ir . GetTaskId ( ) , ir . GetSegments ( ) ) ; err != nil {
2022-06-15 04:20:10 +00:00
log . Error ( "failed to acquire segment ref lock" , zap . Error ( err ) )
return & commonpb . Status {
ErrorCode : commonpb . ErrorCode_UnexpectedError ,
Reason : fmt . Sprintf ( "failed to acquire segment ref lock %s" , err . Error ( ) ) ,
} , nil
}
// Update task store with new segments.
c . importManager . appendTaskSegments ( ir . GetTaskId ( ) , ir . GetSegments ( ) )
return & commonpb . Status {
ErrorCode : commonpb . ErrorCode_Success ,
} , nil
}
2022-03-31 05:51:28 +00:00
// Upon receiving ReportImport request, update the related task's state in task store.
2022-04-01 03:33:28 +00:00
ti , err := c . importManager . updateTaskState ( ir )
2022-03-21 07:47:23 +00:00
if err != nil {
return & commonpb . Status {
2022-03-31 05:51:28 +00:00
ErrorCode : commonpb . ErrorCode_UpdateImportTaskFailure ,
2022-03-21 07:47:23 +00:00
Reason : err . Error ( ) ,
} , nil
2022-03-11 09:13:59 +00:00
}
2022-04-03 03:37:29 +00:00
2022-05-31 07:40:04 +00:00
// This method update a busy node to idle node, and send import task to idle node
resendTaskFunc := func ( ) {
func ( ) {
c . importManager . busyNodesLock . Lock ( )
defer c . importManager . busyNodesLock . Unlock ( )
delete ( c . importManager . busyNodes , ir . GetDatanodeId ( ) )
log . Info ( "DataNode is no longer busy" ,
zap . Int64 ( "dataNode ID" , ir . GetDatanodeId ( ) ) ,
zap . Int64 ( "task ID" , ir . GetTaskId ( ) ) )
} ( )
c . importManager . sendOutTasks ( c . importManager . ctx )
}
// If task failed, send task to idle datanode
if ir . GetState ( ) == commonpb . ImportState_ImportFailed {
2022-06-15 04:20:10 +00:00
// Release segments when task fails.
log . Info ( "task failed, release segment ref locks" )
err := retry . Do ( ctx , func ( ) error {
2022-06-15 13:38:10 +00:00
return c . CallReleaseSegRefLock ( ctx , ir . GetTaskId ( ) , ir . GetSegments ( ) )
2022-06-15 04:20:10 +00:00
} , retry . Attempts ( 100 ) )
if err != nil {
log . Error ( "failed to release lock, about to panic!" )
panic ( err )
}
2022-05-31 07:40:04 +00:00
resendTaskFunc ( )
}
2022-05-05 13:17:50 +00:00
// So much for reporting, unless the task just reached `ImportPersisted` state.
if ir . GetState ( ) != commonpb . ImportState_ImportPersisted {
log . Debug ( "non import-persisted state received, return immediately" ,
zap . Any ( "task ID" , ir . GetTaskId ( ) ) ,
zap . Any ( "import state" , ir . GetState ( ) ) )
2022-04-03 03:37:29 +00:00
return & commonpb . Status {
ErrorCode : commonpb . ErrorCode_Success ,
} , nil
}
2022-05-09 12:47:52 +00:00
// Look up collection name on collection ID.
2022-03-31 05:51:28 +00:00
var colName string
2022-07-22 02:20:29 +00:00
var colMeta * model . Collection
2022-05-09 12:47:52 +00:00
if colMeta , err = c . MetaTable . GetCollectionByID ( ti . GetCollectionId ( ) , 0 ) ; err != nil {
log . Error ( "failed to get collection name" ,
zap . Int64 ( "collection ID" , ti . GetCollectionId ( ) ) ,
zap . Error ( err ) )
2022-06-17 13:14:11 +00:00
// In some unexpected cases, user drop collection when bulkload task still in pending list, the datanode become idle.
// If we directly return, the pending tasks will remain in pending list. So we call resendTaskFunc() to push next pending task to idle datanode.
resendTaskFunc ( )
2022-03-31 05:51:28 +00:00
return & commonpb . Status {
ErrorCode : commonpb . ErrorCode_CollectionNameNotFound ,
2022-05-09 12:47:52 +00:00
Reason : "failed to get collection name for collection ID" + strconv . FormatInt ( ti . GetCollectionId ( ) , 10 ) ,
2022-03-31 05:51:28 +00:00
} , nil
}
2022-07-22 02:20:29 +00:00
colName = colMeta . Name
2022-03-31 05:51:28 +00:00
2022-05-31 07:40:04 +00:00
// When DataNode has done its thing, remove it from the busy node list. And send import task again
resendTaskFunc ( )
2022-04-01 03:33:28 +00:00
2022-05-05 13:17:50 +00:00
// Flush all import data segments.
2022-04-25 03:07:47 +00:00
c . CallFlushOnCollection ( ctx , ti . GetCollectionId ( ) , ir . GetSegments ( ) )
2022-05-05 13:17:50 +00:00
// Check if data are "queryable" and if indices are built on all segments.
go c . postImportPersistLoop ( c . ctx , ir . GetTaskId ( ) , ti . GetCollectionId ( ) , colName , ir . GetSegments ( ) )
2022-03-11 09:13:59 +00:00
2022-03-21 07:47:23 +00:00
return & commonpb . Status {
ErrorCode : commonpb . ErrorCode_Success ,
} , nil
2022-03-11 09:13:59 +00:00
}
2022-03-28 08:41:28 +00:00
2022-06-15 04:20:10 +00:00
// CountCompleteIndex checks indexing status of the given segments.
// It returns an error if error occurs. It also returns a boolean indicating whether indexing is done (or if no index
// is needed).
2022-03-28 08:41:28 +00:00
func ( c * Core ) CountCompleteIndex ( ctx context . Context , collectionName string , collectionID UniqueID ,
2022-06-15 04:20:10 +00:00
allSegmentIDs [ ] UniqueID ) ( bool , error ) {
// Note: Index name is always Params.CommonCfg.DefaultIndexName in current Milvus designs as of today.
2022-03-28 08:41:28 +00:00
indexName := Params . CommonCfg . DefaultIndexName
// Retrieve index status and detailed index information.
describeIndexReq := & milvuspb . DescribeIndexRequest {
Base : & commonpb . MsgBase {
MsgType : commonpb . MsgType_DescribeIndex ,
} ,
CollectionName : collectionName ,
IndexName : indexName ,
}
indexDescriptionResp , err := c . DescribeIndex ( ctx , describeIndexReq )
if err != nil {
2022-06-15 04:20:10 +00:00
return false , err
}
if len ( indexDescriptionResp . GetIndexDescriptions ( ) ) == 0 {
log . Info ( "no index needed for collection, consider indexing done" ,
zap . Int64 ( "collection ID" , collectionID ) )
return true , nil
2022-03-28 08:41:28 +00:00
}
2022-06-15 04:20:10 +00:00
log . Debug ( "got index description" ,
zap . Any ( "index description" , indexDescriptionResp ) )
2022-03-28 08:41:28 +00:00
// Check if the target index name exists.
matchIndexID := int64 ( - 1 )
foundIndexID := false
2022-06-15 04:20:10 +00:00
for _ , desc := range indexDescriptionResp . GetIndexDescriptions ( ) {
if desc . GetIndexName ( ) == indexName {
matchIndexID = desc . GetIndexID ( )
2022-03-28 08:41:28 +00:00
foundIndexID = true
break
}
}
if ! foundIndexID {
2022-06-15 04:20:10 +00:00
return false , fmt . Errorf ( "no index is created" )
2022-03-28 08:41:28 +00:00
}
2022-06-15 04:20:10 +00:00
log . Debug ( "found match index ID" ,
zap . Int64 ( "match index ID" , matchIndexID ) )
2022-03-28 08:41:28 +00:00
getIndexStatesRequest := & indexpb . GetIndexStatesRequest {
IndexBuildIDs : make ( [ ] UniqueID , 0 ) ,
}
// Fetch index build IDs from segments.
2022-06-15 04:20:10 +00:00
var seg2Check [ ] UniqueID
2022-03-28 08:41:28 +00:00
for _ , segmentID := range allSegmentIDs {
describeSegmentRequest := & milvuspb . DescribeSegmentRequest {
Base : & commonpb . MsgBase {
MsgType : commonpb . MsgType_DescribeSegment ,
} ,
CollectionID : collectionID ,
SegmentID : segmentID ,
}
2022-06-15 04:20:10 +00:00
segmentDesc , _ := c . DescribeSegment ( ctx , describeSegmentRequest )
if segmentDesc . GetStatus ( ) . GetErrorCode ( ) != commonpb . ErrorCode_Success {
// Describe failed, since the segment could get compacted, simply log and ignore the error.
log . Error ( "failed to describe segment" ,
2022-03-31 05:51:28 +00:00
zap . Int64 ( "collection ID" , collectionID ) ,
2022-06-15 04:20:10 +00:00
zap . Int64 ( "segment ID" , segmentID ) ,
zap . String ( "error" , segmentDesc . GetStatus ( ) . GetReason ( ) ) )
2022-03-28 08:41:28 +00:00
}
2022-06-15 04:20:10 +00:00
if segmentDesc . GetIndexID ( ) == matchIndexID {
if segmentDesc . GetEnableIndex ( ) {
seg2Check = append ( seg2Check , segmentID )
getIndexStatesRequest . IndexBuildIDs = append ( getIndexStatesRequest . GetIndexBuildIDs ( ) , segmentDesc . GetBuildID ( ) )
2022-03-28 08:41:28 +00:00
}
}
}
2022-06-15 04:20:10 +00:00
if len ( getIndexStatesRequest . GetIndexBuildIDs ( ) ) == 0 {
log . Info ( "none index build IDs returned, perhaps no index is needed" ,
2022-04-03 03:37:29 +00:00
zap . String ( "collection name" , collectionName ) ,
zap . Int64 ( "collection ID" , collectionID ) )
2022-06-15 04:20:10 +00:00
return true , nil
2022-03-28 08:41:28 +00:00
}
2022-06-15 04:20:10 +00:00
log . Debug ( "working on GetIndexState" ,
zap . Int ( "# of IndexBuildIDs" , len ( getIndexStatesRequest . GetIndexBuildIDs ( ) ) ) )
2022-05-05 13:17:50 +00:00
states , err := c . CallGetIndexStatesService ( ctx , getIndexStatesRequest . GetIndexBuildIDs ( ) )
2022-03-28 08:41:28 +00:00
if err != nil {
2022-03-31 05:51:28 +00:00
log . Error ( "failed to get index state in checkSegmentIndexStates" , zap . Error ( err ) )
2022-06-15 04:20:10 +00:00
return false , err
2022-03-28 08:41:28 +00:00
}
// Count the # of segments with finished index.
ct := 0
for _ , s := range states {
if s . State == commonpb . IndexState_Finished {
ct ++
}
}
2022-03-31 05:51:28 +00:00
log . Info ( "segment indexing state checked" ,
2022-06-15 04:20:10 +00:00
zap . Int64s ( "segments checked" , seg2Check ) ,
zap . Int ( "# of checked segment" , len ( seg2Check ) ) ,
2022-03-28 08:41:28 +00:00
zap . Int ( "# of segments with complete index" , ct ) ,
zap . String ( "collection name" , collectionName ) ,
zap . Int64 ( "collection ID" , collectionID ) ,
)
2022-06-15 04:20:10 +00:00
return len ( seg2Check ) == ct , nil
2022-03-28 08:41:28 +00:00
}
2022-03-31 05:51:28 +00:00
2022-05-05 13:17:50 +00:00
func ( c * Core ) postImportPersistLoop ( ctx context . Context , taskID int64 , colID int64 , colName string , segIDs [ ] UniqueID ) {
// Loop and check if segments are loaded in queryNodes.
c . wg . Add ( 1 )
2022-06-15 04:20:10 +00:00
go c . checkSegmentLoadedLoop ( ctx , taskID , colID , segIDs )
2022-05-05 13:17:50 +00:00
// Check if collection has any indexed fields. If so, start a loop to check segments' index states.
2022-05-09 12:47:52 +00:00
if colMeta , err := c . MetaTable . GetCollectionByID ( colID , 0 ) ; err != nil {
log . Error ( "failed to find meta for collection" ,
2022-06-15 04:20:10 +00:00
zap . Int64 ( "collection ID" , colID ) ,
zap . Error ( err ) )
2022-07-22 02:20:29 +00:00
} else if len ( colMeta . FieldIDToIndexID ) == 0 {
2022-06-15 04:20:10 +00:00
log . Info ( "no index field found for collection" , zap . Int64 ( "collection ID" , colID ) )
} else {
log . Info ( "start checking index state" , zap . Int64 ( "collection ID" , colID ) )
2022-05-05 13:17:50 +00:00
c . wg . Add ( 1 )
2022-06-15 04:20:10 +00:00
go c . checkCompleteIndexLoop ( ctx , taskID , colID , colName , segIDs )
2022-05-05 13:17:50 +00:00
}
}
// checkSegmentLoadedLoop loops and checks if all segments in `segIDs` are loaded in queryNodes.
func ( c * Core ) checkSegmentLoadedLoop ( ctx context . Context , taskID int64 , colID int64 , segIDs [ ] UniqueID ) {
2022-03-31 05:51:28 +00:00
defer c . wg . Done ( )
2022-05-05 13:17:50 +00:00
ticker := time . NewTicker ( time . Duration ( Params . RootCoordCfg . ImportSegmentStateCheckInterval * 1000 ) * time . Millisecond )
2022-04-03 03:37:29 +00:00
defer ticker . Stop ( )
2022-05-05 13:17:50 +00:00
expireTicker := time . NewTicker ( time . Duration ( Params . RootCoordCfg . ImportSegmentStateWaitLimit * 1000 ) * time . Millisecond )
2022-04-03 03:37:29 +00:00
defer expireTicker . Stop ( )
2022-06-15 04:20:10 +00:00
defer func ( ) {
log . Info ( "we are done checking segment loading state, release segment ref locks" )
err := retry . Do ( ctx , func ( ) error {
2022-06-15 13:38:10 +00:00
return c . CallReleaseSegRefLock ( ctx , taskID , segIDs )
2022-06-15 04:20:10 +00:00
} , retry . Attempts ( 100 ) )
if err != nil {
log . Error ( "failed to release lock, about to panic!" )
panic ( err )
}
} ( )
2022-03-31 05:51:28 +00:00
for {
select {
case <- c . ctx . Done ( ) :
2022-05-05 13:17:50 +00:00
log . Info ( "(in check segment loaded loop) context done, exiting checkSegmentLoadedLoop" )
2022-03-31 05:51:28 +00:00
return
case <- ticker . C :
2022-05-05 13:17:50 +00:00
resp , err := c . CallGetSegmentInfoService ( ctx , colID , segIDs )
2022-06-15 04:20:10 +00:00
log . Debug ( "(in check segment loaded loop)" ,
zap . Int64 ( "task ID" , taskID ) ,
zap . Int64 ( "collection ID" , colID ) ,
zap . Int64s ( "segment IDs expected" , segIDs ) ,
zap . Int ( "# of segments found" , len ( resp . GetInfos ( ) ) ) )
2022-05-05 13:17:50 +00:00
if err != nil {
2022-05-06 13:35:51 +00:00
log . Warn ( "(in check segment loaded loop) failed to call get segment info on queryCoord" ,
zap . Int64 ( "task ID" , taskID ) ,
2022-05-05 13:17:50 +00:00
zap . Int64 ( "collection ID" , colID ) ,
zap . Int64s ( "segment IDs" , segIDs ) )
2022-06-15 04:20:10 +00:00
} else if len ( resp . GetInfos ( ) ) == len ( segIDs ) {
2022-05-05 13:17:50 +00:00
// Check if all segment info are loaded in queryNodes.
2022-05-06 13:35:51 +00:00
log . Info ( "(in check segment loaded loop) all import data segments loaded in queryNodes" ,
zap . Int64 ( "task ID" , taskID ) ,
2022-05-05 13:17:50 +00:00
zap . Int64 ( "collection ID" , colID ) ,
zap . Int64s ( "segment IDs" , segIDs ) )
2022-05-12 11:23:53 +00:00
c . importManager . setTaskDataQueryable ( taskID )
2022-03-31 05:51:28 +00:00
return
}
case <- expireTicker . C :
2022-05-05 13:17:50 +00:00
log . Warn ( "(in check segment loaded loop) segments still not loaded after max wait time" ,
zap . Int64 ( "task ID" , taskID ) ,
zap . Int64 ( "collection ID" , colID ) ,
zap . Int64s ( "segment IDs" , segIDs ) )
2022-03-31 05:51:28 +00:00
return
}
}
}
2022-05-05 13:17:50 +00:00
// checkCompleteIndexLoop loops and checks if all indices are built for an import task's segments.
func ( c * Core ) checkCompleteIndexLoop ( ctx context . Context , taskID int64 , colID int64 , colName string , segIDs [ ] UniqueID ) {
defer c . wg . Done ( )
ticker := time . NewTicker ( time . Duration ( Params . RootCoordCfg . ImportIndexCheckInterval * 1000 ) * time . Millisecond )
defer ticker . Stop ( )
expireTicker := time . NewTicker ( time . Duration ( Params . RootCoordCfg . ImportIndexWaitLimit * 1000 ) * time . Millisecond )
defer expireTicker . Stop ( )
for {
select {
case <- c . ctx . Done ( ) :
log . Info ( "(in check complete index loop) context done, exiting checkCompleteIndexLoop" )
return
case <- ticker . C :
2022-06-15 04:20:10 +00:00
if done , err := c . CountCompleteIndex ( ctx , colName , colID , segIDs ) ; err == nil && done {
log . Info ( "(in check complete index loop) indices are built or no index needed" ,
2022-05-06 13:35:51 +00:00
zap . Int64 ( "task ID" , taskID ) )
2022-05-12 11:23:53 +00:00
c . importManager . setTaskDataIndexed ( taskID )
2022-05-05 13:17:50 +00:00
return
2022-06-15 04:20:10 +00:00
} else if err != nil {
log . Error ( "(in check complete index loop) an error occurs" ,
zap . Error ( err ) )
2022-05-05 13:17:50 +00:00
}
case <- expireTicker . C :
log . Warn ( "(in check complete index loop) indexing is taken too long" ,
zap . Int64 ( "task ID" , taskID ) ,
zap . Int64 ( "collection ID" , colID ) ,
zap . Int64s ( "segment IDs" , segIDs ) )
return
}
2022-03-31 05:51:28 +00:00
}
}
2022-04-11 11:49:34 +00:00
// ExpireCredCache will call invalidate credential cache
func ( c * Core ) ExpireCredCache ( ctx context . Context , username string ) error {
req := proxypb . InvalidateCredCacheRequest {
Base : & commonpb . MsgBase {
MsgType : 0 , //TODO, msg type
MsgID : 0 , //TODO, msg id
SourceID : c . session . ServerID ,
} ,
Username : username ,
}
return c . proxyClientManager . InvalidateCredentialCache ( ctx , & req )
}
// UpdateCredCache will call update credential cache
func ( c * Core ) UpdateCredCache ( ctx context . Context , credInfo * internalpb . CredentialInfo ) error {
req := proxypb . UpdateCredCacheRequest {
Base : & commonpb . MsgBase {
MsgType : 0 , //TODO, msg type
MsgID : 0 , //TODO, msg id
SourceID : c . session . ServerID ,
} ,
Username : credInfo . Username ,
2022-06-29 12:02:18 +00:00
Password : credInfo . Sha256Password ,
2022-04-11 11:49:34 +00:00
}
return c . proxyClientManager . UpdateCredentialCache ( ctx , & req )
}
// CreateCredential create new user and password
// 1. decode ciphertext password to raw password
// 2. encrypt raw password
// 3. save in to etcd
func ( c * Core ) CreateCredential ( ctx context . Context , credInfo * internalpb . CredentialInfo ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
method := "CreateCredential"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
2022-04-11 11:49:34 +00:00
log . Debug ( "CreateCredential" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , credInfo . Username ) )
2022-08-04 03:04:34 +00:00
usersInfo , err := c . MetaTable . ListCredentialUsernames ( )
if err != nil {
log . Error ( "CreateCredential get credential username list failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , credInfo . Username ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_CreateCredentialFailure , "CreateCredential failed, fail to get credential username list to check the user number, error: " + err . Error ( ) ) , nil
}
if len ( usersInfo . Usernames ) >= Params . ProxyCfg . MaxUserNum {
return failStatus ( commonpb . ErrorCode_CreateCredentialFailure , "unable to add user because the number of users has reached the limit" ) , nil
}
2022-04-11 11:49:34 +00:00
if cred , _ := c . MetaTable . getCredential ( credInfo . Username ) ; cred != nil {
return failStatus ( commonpb . ErrorCode_CreateCredentialFailure , "user already exists:" + credInfo . Username ) , nil
}
2022-06-29 12:02:18 +00:00
// insert to db
2022-08-04 03:04:34 +00:00
err = c . MetaTable . AddCredential ( credInfo )
2022-04-11 11:49:34 +00:00
if err != nil {
2022-06-29 12:02:18 +00:00
log . Error ( "CreateCredential save credential failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-11 11:49:34 +00:00
zap . String ( "username" , credInfo . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-04-11 11:49:34 +00:00
return failStatus ( commonpb . ErrorCode_CreateCredentialFailure , "CreateCredential failed: " + err . Error ( ) ) , nil
}
2022-06-29 12:02:18 +00:00
// update proxy's local cache
err = c . UpdateCredCache ( ctx , credInfo )
2022-04-11 11:49:34 +00:00
if err != nil {
2022-06-29 12:02:18 +00:00
log . Warn ( "CreateCredential add cache failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-11 11:49:34 +00:00
zap . String ( "username" , credInfo . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-04-11 11:49:34 +00:00
}
log . Debug ( "CreateCredential success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , credInfo . Username ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-11 11:49:34 +00:00
metrics . RootCoordNumOfCredentials . Inc ( )
return succStatus ( ) , nil
}
// GetCredential get credential by username
func ( c * Core ) GetCredential ( ctx context . Context , in * rootcoordpb . GetCredentialRequest ) ( * rootcoordpb . GetCredentialResponse , error ) {
2022-04-27 15:03:47 +00:00
method := "GetCredential"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
2022-04-11 11:49:34 +00:00
log . Debug ( "GetCredential" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , in . Username ) )
credInfo , err := c . MetaTable . getCredential ( in . Username )
if err != nil {
log . Error ( "GetCredential query credential failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , in . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-04-11 11:49:34 +00:00
return & rootcoordpb . GetCredentialResponse {
Status : failStatus ( commonpb . ErrorCode_GetCredentialFailure , "GetCredential failed: " + err . Error ( ) ) ,
} , err
}
log . Debug ( "GetCredential success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , in . Username ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-11 11:49:34 +00:00
return & rootcoordpb . GetCredentialResponse {
Status : succStatus ( ) ,
Username : credInfo . Username ,
Password : credInfo . EncryptedPassword ,
} , nil
}
// UpdateCredential update password for a user
func ( c * Core ) UpdateCredential ( ctx context . Context , credInfo * internalpb . CredentialInfo ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
method := "UpdateCredential"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
2022-04-11 11:49:34 +00:00
log . Debug ( "UpdateCredential" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , credInfo . Username ) )
2022-06-29 12:02:18 +00:00
// update data on storage
err := c . MetaTable . AddCredential ( credInfo )
2022-04-11 11:49:34 +00:00
if err != nil {
2022-06-29 12:02:18 +00:00
log . Error ( "UpdateCredential save credential failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-11 11:49:34 +00:00
zap . String ( "username" , credInfo . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-04-11 11:49:34 +00:00
return failStatus ( commonpb . ErrorCode_UpdateCredentialFailure , "UpdateCredential failed: " + err . Error ( ) ) , nil
}
2022-06-29 12:02:18 +00:00
// update proxy's local cache
err = c . UpdateCredCache ( ctx , credInfo )
2022-04-11 11:49:34 +00:00
if err != nil {
2022-06-29 12:02:18 +00:00
log . Error ( "UpdateCredential update cache failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-11 11:49:34 +00:00
zap . String ( "username" , credInfo . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-04-11 11:49:34 +00:00
return failStatus ( commonpb . ErrorCode_UpdateCredentialFailure , "UpdateCredential failed: " + err . Error ( ) ) , nil
}
log . Debug ( "UpdateCredential success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , credInfo . Username ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-11 11:49:34 +00:00
return succStatus ( ) , nil
}
// DeleteCredential delete a user
func ( c * Core ) DeleteCredential ( ctx context . Context , in * milvuspb . DeleteCredentialRequest ) ( * commonpb . Status , error ) {
2022-04-27 15:03:47 +00:00
method := "DeleteCredential"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
2022-04-11 11:49:34 +00:00
2022-06-29 12:02:18 +00:00
// delete data on storage
err := c . MetaTable . DeleteCredential ( in . Username )
2022-04-11 11:49:34 +00:00
if err != nil {
2022-06-29 12:02:18 +00:00
log . Error ( "DeleteCredential remove credential failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-11 11:49:34 +00:00
zap . String ( "username" , in . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-06-29 12:02:18 +00:00
return failStatus ( commonpb . ErrorCode_DeleteCredentialFailure , "DeleteCredential failed: " + err . Error ( ) ) , err
2022-04-11 11:49:34 +00:00
}
2022-06-29 12:02:18 +00:00
// invalidate proxy's local cache
err = c . ExpireCredCache ( ctx , in . Username )
2022-04-11 11:49:34 +00:00
if err != nil {
2022-06-29 12:02:18 +00:00
log . Error ( "DeleteCredential expire credential cache failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
2022-04-11 11:49:34 +00:00
zap . String ( "username" , in . Username ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-06-29 12:02:18 +00:00
return failStatus ( commonpb . ErrorCode_DeleteCredentialFailure , "DeleteCredential failed: " + err . Error ( ) ) , nil
2022-04-11 11:49:34 +00:00
}
log . Debug ( "DeleteCredential success" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . String ( "username" , in . Username ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-11 11:49:34 +00:00
metrics . RootCoordNumOfCredentials . Dec ( )
return succStatus ( ) , nil
}
// ListCredUsers list all usernames
func ( c * Core ) ListCredUsers ( ctx context . Context , in * milvuspb . ListCredUsersRequest ) ( * milvuspb . ListCredUsersResponse , error ) {
2022-04-27 15:03:47 +00:00
method := "ListCredUsers"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
2022-04-11 11:49:34 +00:00
credInfo , err := c . MetaTable . ListCredentialUsernames ( )
if err != nil {
log . Error ( "ListCredUsers query usernames failed" , zap . String ( "role" , typeutil . RootCoordRole ) ,
zap . Int64 ( "msgID" , in . Base . MsgID ) , zap . Error ( err ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . FailLabel ) . Inc ( )
2022-04-11 11:49:34 +00:00
return & milvuspb . ListCredUsersResponse {
Status : failStatus ( commonpb . ErrorCode_ListCredUsersFailure , "ListCredUsers failed: " + err . Error ( ) ) ,
} , err
}
log . Debug ( "ListCredUsers success" , zap . String ( "role" , typeutil . RootCoordRole ) )
2022-04-27 15:03:47 +00:00
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
2022-04-11 11:49:34 +00:00
return & milvuspb . ListCredUsersResponse {
Status : succStatus ( ) ,
Usernames : credInfo . Usernames ,
} , nil
}
2022-08-04 03:04:34 +00:00
// CreateRole create role
// - check the node health
// - check if the role is existed
// - check if the role num has reached the limit
// - create the role by the metatable api
func ( c * Core ) CreateRole ( ctx context . Context , in * milvuspb . CreateRoleRequest ) ( * commonpb . Status , error ) {
method := "CreateRole"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return errorutil . UnhealthyStatus ( code ) , errorutil . UnhealthyError ( )
}
entity := in . Entity
results , err := c . MetaTable . SelectRole ( util . DefaultTenant , nil , false )
if err != nil {
logger . Error ( "fail to select roles" , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_CreateRoleFailure , "fail to select roles to check the role number, error: " + err . Error ( ) ) , err
}
if len ( results ) >= Params . ProxyCfg . MaxRoleNum {
errMsg := "unable to add role because the number of roles has reached the limit"
return failStatus ( commonpb . ErrorCode_CreateRoleFailure , errMsg ) , errors . New ( errMsg )
}
err = c . MetaTable . CreateRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : entity . Name } )
if err != nil {
logger . Error ( "fail to create role" , zap . String ( "role_name" , entity . Name ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_CreateRoleFailure , "CreateCollection role failed: " + err . Error ( ) ) , err
}
logger . Debug ( method + " success" , zap . String ( "role_name" , entity . Name ) )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
metrics . RootCoordNumOfRoles . Inc ( )
return succStatus ( ) , nil
}
// DropRole drop role
// - check the node health
// - check if the role name is existed
// - check if the role has some grant info
// - get all role mapping of this role
// - drop these role mappings
// - drop the role by the metatable api
func ( c * Core ) DropRole ( ctx context . Context , in * milvuspb . DropRoleRequest ) ( * commonpb . Status , error ) {
method := "DropRole"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return errorutil . UnhealthyStatus ( code ) , errorutil . UnhealthyError ( )
}
if _ , err := c . MetaTable . SelectRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : in . RoleName } , false ) ; err != nil {
logger . Error ( "the role isn't existed" , zap . String ( "role_name" , in . RoleName ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_DropRoleFailure , fmt . Sprintf ( "the role isn't existed, role name: %s" , in . RoleName ) ) , err
}
grantEntities , err := c . MetaTable . SelectGrant ( util . DefaultTenant , & milvuspb . GrantEntity {
Role : & milvuspb . RoleEntity { Name : in . RoleName } ,
} )
if len ( grantEntities ) != 0 {
errMsg := "fail to drop the role that it has privileges. Use REVOKE API to revoke privileges"
logger . Error ( errMsg , zap . String ( "role_name" , in . RoleName ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_DropRoleFailure , errMsg ) , errors . New ( errMsg )
}
roleResults , err := c . MetaTable . SelectRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : in . RoleName } , true )
if err != nil {
errMsg := "fail to select a role by role name"
logger . Error ( "fail to select a role by role name" , zap . String ( "role_name" , in . RoleName ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_DropRoleFailure , errMsg ) , err
}
logger . Debug ( "role to user info" , zap . Int ( "counter" , len ( roleResults ) ) )
for _ , roleResult := range roleResults {
for index , userEntity := range roleResult . Users {
if err = c . MetaTable . OperateUserRole ( util . DefaultTenant , & milvuspb . UserEntity { Name : userEntity . Name } , & milvuspb . RoleEntity { Name : roleResult . Role . Name } , milvuspb . OperateUserRoleType_RemoveUserFromRole ) ; err != nil {
2022-08-23 02:26:53 +00:00
if common . IsIgnorableError ( err ) {
continue
}
2022-08-04 03:04:34 +00:00
errMsg := "fail to remove user from role"
logger . Error ( errMsg , zap . String ( "role_name" , roleResult . Role . Name ) , zap . String ( "username" , userEntity . Name ) , zap . Int ( "current_index" , index ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_OperateUserRoleFailure , errMsg ) , err
}
}
}
if err = c . MetaTable . DropRole ( util . DefaultTenant , in . RoleName ) ; err != nil {
errMsg := "fail to drop the role"
logger . Error ( errMsg , zap . String ( "role_name" , in . RoleName ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_DropRoleFailure , errMsg ) , err
}
logger . Debug ( method + " success" , zap . String ( "role_name" , in . RoleName ) )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
metrics . RootCoordNumOfRoles . Dec ( )
return succStatus ( ) , nil
}
// OperateUserRole operate the relationship between a user and a role
// - check the node health
// - check if the role is valid
// - check if the user is valid
// - operate the user-role by the metatable api
// - update the policy cache
func ( c * Core ) OperateUserRole ( ctx context . Context , in * milvuspb . OperateUserRoleRequest ) ( * commonpb . Status , error ) {
method := "OperateUserRole-" + in . Type . String ( )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return errorutil . UnhealthyStatus ( code ) , errorutil . UnhealthyError ( )
}
if _ , err := c . MetaTable . SelectRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : in . RoleName } , false ) ; err != nil {
errMsg := "fail to check the role name"
logger . Error ( errMsg , zap . String ( "role_name" , in . RoleName ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_OperateUserRoleFailure , errMsg ) , err
}
if _ , err := c . MetaTable . SelectUser ( util . DefaultTenant , & milvuspb . UserEntity { Name : in . Username } , false ) ; err != nil {
errMsg := "fail to check the username"
logger . Error ( errMsg , zap . String ( "username" , in . Username ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_OperateUserRoleFailure , errMsg ) , err
}
2022-08-23 02:26:53 +00:00
updateCache := true
2022-08-04 03:04:34 +00:00
if err := c . MetaTable . OperateUserRole ( util . DefaultTenant , & milvuspb . UserEntity { Name : in . Username } , & milvuspb . RoleEntity { Name : in . RoleName } , in . Type ) ; err != nil {
2022-08-23 02:26:53 +00:00
if ! common . IsIgnorableError ( err ) {
errMsg := "fail to operate user to role"
logger . Error ( errMsg , zap . String ( "role_name" , in . RoleName ) , zap . String ( "username" , in . Username ) , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_OperateUserRoleFailure , errMsg ) , err
}
updateCache = false
2022-08-04 03:04:34 +00:00
}
2022-08-23 02:26:53 +00:00
if updateCache {
var opType int32
switch in . Type {
case milvuspb . OperateUserRoleType_AddUserToRole :
opType = int32 ( typeutil . CacheAddUserToRole )
case milvuspb . OperateUserRoleType_RemoveUserFromRole :
opType = int32 ( typeutil . CacheRemoveUserFromRole )
default :
errMsg := "invalid operate type for the OperateUserRole api"
logger . Error ( errMsg , zap . Any ( "op_type" , in . Type ) )
return failStatus ( commonpb . ErrorCode_OperateUserRoleFailure , errMsg ) , errors . New ( errMsg )
}
if err := c . proxyClientManager . RefreshPolicyInfoCache ( ctx , & proxypb . RefreshPolicyInfoCacheRequest {
OpType : opType ,
OpKey : funcutil . EncodeUserRoleCache ( in . Username , in . RoleName ) ,
} ) ; err != nil {
return failStatus ( commonpb . ErrorCode_OperateUserRoleFailure , err . Error ( ) ) , err
}
2022-08-04 03:04:34 +00:00
}
logger . Debug ( method + " success" )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
return succStatus ( ) , nil
}
// SelectRole select role
// - check the node health
// - check if the role is valid when this param is provided
// - select role by the metatable api
func ( c * Core ) SelectRole ( ctx context . Context , in * milvuspb . SelectRoleRequest ) ( * milvuspb . SelectRoleResponse , error ) {
method := "SelectRole"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return & milvuspb . SelectRoleResponse { Status : errorutil . UnhealthyStatus ( code ) } , errorutil . UnhealthyError ( )
}
if in . Role != nil {
if _ , err := c . MetaTable . SelectRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : in . Role . Name } , false ) ; err != nil {
errMsg := "fail to select the role to check the role name"
logger . Error ( errMsg , zap . String ( "role_name" , in . Role . Name ) , zap . Error ( err ) )
2022-08-10 09:20:41 +00:00
if common . IsKeyNotExistError ( err ) {
return & milvuspb . SelectRoleResponse {
Status : succStatus ( ) ,
} , nil
}
2022-08-04 03:04:34 +00:00
return & milvuspb . SelectRoleResponse {
Status : failStatus ( commonpb . ErrorCode_SelectRoleFailure , errMsg ) ,
} , err
}
}
roleResults , err := c . MetaTable . SelectRole ( util . DefaultTenant , in . Role , in . IncludeUserInfo )
if err != nil {
errMsg := "fail to select the role"
logger . Error ( errMsg , zap . Error ( err ) )
return & milvuspb . SelectRoleResponse {
Status : failStatus ( commonpb . ErrorCode_SelectRoleFailure , errMsg ) ,
} , err
}
logger . Debug ( method + " success" )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
return & milvuspb . SelectRoleResponse {
Status : succStatus ( ) ,
Results : roleResults ,
} , nil
}
// SelectUser select user
// - check the node health
// - check if the user is valid when this param is provided
// - select user by the metatable api
func ( c * Core ) SelectUser ( ctx context . Context , in * milvuspb . SelectUserRequest ) ( * milvuspb . SelectUserResponse , error ) {
method := "SelectUser"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return & milvuspb . SelectUserResponse { Status : errorutil . UnhealthyStatus ( code ) } , errorutil . UnhealthyError ( )
}
if in . User != nil {
if _ , err := c . MetaTable . SelectUser ( util . DefaultTenant , & milvuspb . UserEntity { Name : in . User . Name } , false ) ; err != nil {
errMsg := "fail to select the user to check the username"
logger . Error ( errMsg , zap . String ( "username" , in . User . Name ) , zap . Error ( err ) )
2022-08-10 09:20:41 +00:00
if common . IsKeyNotExistError ( err ) {
return & milvuspb . SelectUserResponse {
Status : succStatus ( ) ,
} , nil
}
2022-08-04 03:04:34 +00:00
return & milvuspb . SelectUserResponse {
Status : failStatus ( commonpb . ErrorCode_SelectUserFailure , errMsg ) ,
} , err
}
}
userResults , err := c . MetaTable . SelectUser ( util . DefaultTenant , in . User , in . IncludeRoleInfo )
if err != nil {
errMsg := "fail to select the user"
log . Error ( errMsg , zap . Error ( err ) )
return & milvuspb . SelectUserResponse {
Status : failStatus ( commonpb . ErrorCode_SelectUserFailure , errMsg ) ,
} , err
}
logger . Debug ( method + " success" )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
return & milvuspb . SelectUserResponse {
Status : succStatus ( ) ,
Results : userResults ,
} , nil
}
func ( c * Core ) isValidRole ( entity * milvuspb . RoleEntity ) error {
if entity == nil {
return fmt . Errorf ( "the role entity is nil" )
}
if entity . Name == "" {
return fmt . Errorf ( "the name in the role entity is empty" )
}
if _ , err := c . MetaTable . SelectRole ( util . DefaultTenant , & milvuspb . RoleEntity { Name : entity . Name } , false ) ; err != nil {
return err
}
return nil
}
func ( c * Core ) isValidObject ( entity * milvuspb . ObjectEntity ) error {
if entity == nil {
return fmt . Errorf ( "the object entity is nil" )
}
if _ , ok := commonpb . ObjectType_value [ entity . Name ] ; ! ok {
return fmt . Errorf ( "the object type in the object entity is invalid, current value: %s" , entity . Name )
}
return nil
}
func ( c * Core ) isValidGrantor ( entity * milvuspb . GrantorEntity , object string ) error {
if entity == nil {
return fmt . Errorf ( "the grantor entity is nil" )
}
if entity . User == nil {
return fmt . Errorf ( "the user entity in the grantor entity is nil" )
}
if entity . User . Name == "" {
return fmt . Errorf ( "the name in the user entity of the grantor entity is empty" )
}
if _ , err := c . MetaTable . SelectUser ( util . DefaultTenant , & milvuspb . UserEntity { Name : entity . GetUser ( ) . Name } , false ) ; err != nil {
return err
}
if entity . Privilege == nil {
return fmt . Errorf ( "the privilege entity in the grantor entity is nil" )
}
2022-08-15 08:40:48 +00:00
if util . IsAnyWord ( entity . Privilege . Name ) {
return nil
}
2022-08-05 08:28:35 +00:00
if privilegeName := util . PrivilegeNameForMetastore ( entity . Privilege . Name ) ; privilegeName == "" {
2022-08-04 03:04:34 +00:00
return fmt . Errorf ( "the privilege name in the privilege entity is invalid, current value: %s" , entity . Privilege . Name )
}
2022-08-15 08:40:48 +00:00
privileges , ok := util . ObjectPrivileges [ object ]
2022-08-04 03:04:34 +00:00
if ! ok {
return fmt . Errorf ( "the object type is invalid, current value: %s" , object )
}
for _ , privilege := range privileges {
if privilege == entity . Privilege . Name {
return nil
}
}
return fmt . Errorf ( "the privilege name is invalid, current value: %s" , entity . Privilege . Name )
}
// OperatePrivilege operate the privilege, including grant and revoke
// - check the node health
// - check if the operating type is valid
// - check if the entity is nil
// - check if the params, including the resource entity, the principal entity, the grantor entity, is valid
// - operate the privilege by the metatable api
// - update the policy cache
func ( c * Core ) OperatePrivilege ( ctx context . Context , in * milvuspb . OperatePrivilegeRequest ) ( * commonpb . Status , error ) {
method := "OperatePrivilege"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return errorutil . UnhealthyStatus ( code ) , errorutil . UnhealthyError ( )
}
if in . Type != milvuspb . OperatePrivilegeType_Grant && in . Type != milvuspb . OperatePrivilegeType_Revoke {
errMsg := fmt . Sprintf ( "invalid operate privilege type, current type: %s, valid value: [%s, %s]" , in . Type , milvuspb . OperatePrivilegeType_Grant , milvuspb . OperatePrivilegeType_Revoke )
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , errMsg ) , errors . New ( errMsg )
}
if in . Entity == nil {
errMsg := "the grant entity in the request is nil"
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , errMsg ) , errors . New ( errMsg )
}
if err := c . isValidObject ( in . Entity . Object ) ; err != nil {
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , err . Error ( ) ) , err
}
if err := c . isValidRole ( in . Entity . Role ) ; err != nil {
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , err . Error ( ) ) , err
}
if err := c . isValidGrantor ( in . Entity . Grantor , in . Entity . Object . Name ) ; err != nil {
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , err . Error ( ) ) , err
}
2022-08-05 08:28:35 +00:00
logger . Debug ( "before PrivilegeNameForMetastore" , zap . String ( "privilege" , in . Entity . Grantor . Privilege . Name ) )
2022-08-15 08:40:48 +00:00
if ! util . IsAnyWord ( in . Entity . Grantor . Privilege . Name ) {
in . Entity . Grantor . Privilege . Name = util . PrivilegeNameForMetastore ( in . Entity . Grantor . Privilege . Name )
}
2022-08-05 08:28:35 +00:00
logger . Debug ( "after PrivilegeNameForMetastore" , zap . String ( "privilege" , in . Entity . Grantor . Privilege . Name ) )
2022-08-04 03:04:34 +00:00
if in . Entity . Object . Name == commonpb . ObjectType_Global . String ( ) {
2022-08-15 08:40:48 +00:00
in . Entity . ObjectName = util . AnyWord
2022-08-04 03:04:34 +00:00
}
2022-08-23 02:26:53 +00:00
updateCache := true
2022-08-04 03:04:34 +00:00
if err := c . MetaTable . OperatePrivilege ( util . DefaultTenant , in . Entity , in . Type ) ; err != nil {
2022-08-23 02:26:53 +00:00
if ! common . IsIgnorableError ( err ) {
errMsg := "fail to operate the privilege"
logger . Error ( errMsg , zap . Error ( err ) )
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , errMsg ) , err
}
updateCache = false
2022-08-04 03:04:34 +00:00
}
2022-08-23 02:26:53 +00:00
if updateCache {
var opType int32
switch in . Type {
case milvuspb . OperatePrivilegeType_Grant :
opType = int32 ( typeutil . CacheGrantPrivilege )
case milvuspb . OperatePrivilegeType_Revoke :
opType = int32 ( typeutil . CacheRevokePrivilege )
default :
errMsg := "invalid operate type for the OperatePrivilege api"
logger . Error ( errMsg , zap . Any ( "op_type" , in . Type ) )
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , errMsg ) , errors . New ( errMsg )
}
if err := c . proxyClientManager . RefreshPolicyInfoCache ( ctx , & proxypb . RefreshPolicyInfoCacheRequest {
OpType : opType ,
OpKey : funcutil . PolicyForPrivilege ( in . Entity . Role . Name , in . Entity . Object . Name , in . Entity . ObjectName , in . Entity . Grantor . Privilege . Name ) ,
} ) ; err != nil {
return failStatus ( commonpb . ErrorCode_OperatePrivilegeFailure , err . Error ( ) ) , err
}
2022-08-04 03:04:34 +00:00
}
logger . Debug ( method + " success" )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
return succStatus ( ) , nil
}
// SelectGrant select grant
// - check the node health
// - check if the principal entity is valid
// - check if the resource entity which is provided by the user is valid
// - select grant by the metatable api
func ( c * Core ) SelectGrant ( ctx context . Context , in * milvuspb . SelectGrantRequest ) ( * milvuspb . SelectGrantResponse , error ) {
method := "SelectGrant"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return & milvuspb . SelectGrantResponse {
Status : errorutil . UnhealthyStatus ( code ) ,
} , errorutil . UnhealthyError ( )
}
if in . Entity == nil {
errMsg := "the grant entity in the request is nil"
return & milvuspb . SelectGrantResponse {
Status : failStatus ( commonpb . ErrorCode_SelectGrantFailure , errMsg ) ,
} , errors . New ( errMsg )
}
if err := c . isValidRole ( in . Entity . Role ) ; err != nil {
return & milvuspb . SelectGrantResponse {
Status : failStatus ( commonpb . ErrorCode_SelectGrantFailure , err . Error ( ) ) ,
} , err
}
if in . Entity . Object != nil {
if err := c . isValidObject ( in . Entity . Object ) ; err != nil {
return & milvuspb . SelectGrantResponse {
Status : failStatus ( commonpb . ErrorCode_SelectGrantFailure , err . Error ( ) ) ,
} , err
}
}
grantEntities , err := c . MetaTable . SelectGrant ( util . DefaultTenant , in . Entity )
2022-08-23 02:26:53 +00:00
if common . IsKeyNotExistError ( err ) {
return & milvuspb . SelectGrantResponse {
Status : succStatus ( ) ,
} , nil
}
2022-08-04 03:04:34 +00:00
if err != nil {
errMsg := "fail to select the grant"
logger . Error ( errMsg , zap . Error ( err ) )
return & milvuspb . SelectGrantResponse {
Status : failStatus ( commonpb . ErrorCode_SelectGrantFailure , errMsg ) ,
} , err
}
logger . Debug ( method + " success" )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
return & milvuspb . SelectGrantResponse {
Status : succStatus ( ) ,
Entities : grantEntities ,
} , nil
}
func ( c * Core ) ListPolicy ( ctx context . Context , in * internalpb . ListPolicyRequest ) ( * internalpb . ListPolicyResponse , error ) {
method := "PolicyList"
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . TotalLabel ) . Inc ( )
tr := timerecord . NewTimeRecorder ( method )
logger . Debug ( method , zap . Any ( "in" , in ) )
if code , ok := c . checkHealthy ( ) ; ! ok {
return & internalpb . ListPolicyResponse {
Status : errorutil . UnhealthyStatus ( code ) ,
} , errorutil . UnhealthyError ( )
}
policies , err := c . MetaTable . ListPolicy ( util . DefaultTenant )
if err != nil {
return & internalpb . ListPolicyResponse {
Status : failStatus ( commonpb . ErrorCode_ListPolicyFailure , "fail to list policy" ) ,
} , err
}
userRoles , err := c . MetaTable . ListUserRole ( util . DefaultTenant )
if err != nil {
return & internalpb . ListPolicyResponse {
Status : failStatus ( commonpb . ErrorCode_ListPolicyFailure , "fail to list user-role" ) ,
} , err
}
logger . Debug ( method + " success" )
metrics . RootCoordDDLReqCounter . WithLabelValues ( method , metrics . SuccessLabel ) . Inc ( )
metrics . RootCoordDDLReqLatency . WithLabelValues ( method ) . Observe ( float64 ( tr . ElapseSpan ( ) . Milliseconds ( ) ) )
return & internalpb . ListPolicyResponse {
Status : succStatus ( ) ,
PolicyInfos : policies ,
UserRoles : userRoles ,
} , nil
}