milvus/internal/dataservice/binlog_helper.go
sunby 189ac881f3 Fix bugs (#5676)
* Remove redundant session startup

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Register datanode after start success

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* fix meta snap shot

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* fix datanode message stream channel

Signed-off-by: yangxuan <xuan.yang@zilliz.com>

* Fix bugs when drop empty collection

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Fix bug of getting pchan statistics from task scheduler

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* Fix i/dist/dataservice test code

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* Fix epoch lifetime not applied

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* fix datanode flowgraph dd node

Signed-off-by: yangxuan <xuan.yang@zilliz.com>

* Fix handle datanode timetick bug

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Remove repack function of dml stream

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* fix proxynode

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Apply extended seal policy

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* add check for time tick

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* fix check

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Fix the repack function of dml stream

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* Fix the bug when send statistics of pchan

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* Fix the repack function when craete dml stream

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* fix bugs

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* fix describe collection

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Fix bug when send timestamp statistics

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* fix data node

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Add length check before flush request

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* add log for data node

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Fix SaveBinlog bugs

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Add more log in datanode

Signed-off-by: yangxuan <xuan.yang@zilliz.com>

* Put SegmentState.Flushing as the last one in enum to fit the client

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Fix params in GetInsertBinlogPaths

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Rename policy

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Remove unused ddl functions and fields

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* Remove pchan when drop collection

Signed-off-by: dragondriver <jiquan.long@zilliz.com>

* Add balanced assignment policy

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* fix master ut

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Add lock in session manager

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* add log for debug

Signed-off-by: yefu.chen <yefu.chen@zilliz.com>

* Fix some logic bug and typo

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

* Fix recover bugs

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Get collection scheme of a specific timestamp

Signed-off-by: yangxuan <xuan.yang@zilliz.com>

* Change CheckPoint to SegmentInfo in VchannelInfo

Signed-off-by: sunby <bingyi.sun@zilliz.com>

* Recover Unflushed segment numOfRows

Signed-off-by: yangxuan <xuan.yang@zilliz.com>

* Fix dataservice unit tests

Signed-off-by: sunby <bingyi.sun@zilliz.com>

Co-authored-by: yefu.chen <yefu.chen@zilliz.com>
Co-authored-by: yangxuan <xuan.yang@zilliz.com>
Co-authored-by: dragondriver <jiquan.long@zilliz.com>
Co-authored-by: Congqi Xia <congqi.xia@zilliz.com>
2021-06-15 16:06:11 +08:00

180 lines
4.8 KiB
Go

package dataservice
import (
"errors"
"path"
"strconv"
"github.com/golang/protobuf/proto"
"github.com/milvus-io/milvus/internal/proto/commonpb"
"github.com/milvus-io/milvus/internal/proto/datapb"
"github.com/milvus-io/milvus/internal/proto/internalpb"
)
// binlog helper functions persisting binlog paths into kv storage.
// migrated from datanode[Author XuanYang-cn]
// ddl binlog etcd meta key:
// ${prefix}/${collectionID}/${idx}
// segment binlog etcd meta key:
// ${prefix}/${segmentID}/${fieldID}/${idx}
// genKey gives a valid key string for lists of UniqueIDs:
// if alloc is true, the returned keys will have a generated-unique ID at the end.
// if alloc is false, the returned keys will only consist of provided ids.
func (s *Server) genKey(alloc bool, ids ...UniqueID) (key string, err error) {
if alloc {
idx, err := s.allocator.allocID()
if err != nil {
return "", err
}
ids = append(ids, idx)
}
idStr := make([]string, len(ids))
for _, id := range ids {
idStr = append(idStr, strconv.FormatInt(id, 10))
}
key = path.Join(idStr...)
return key, nil
}
var (
errNilKvClient = errors.New("kv client not initialized")
errNilID2Paths = errors.New("nil ID2PathList")
errNilSegmentInfo = errors.New("nil segment info")
)
//SaveBinLogMetaTxn saves segment-field2Path, collection-tsPath into kv store in transcation
func (s *Server) SaveBinLogMetaTxn(meta map[string]string) error {
if s.kvClient == nil {
return errNilKvClient
}
return s.kvClient.MultiSave(meta)
}
// prepareField2PathMeta parses fields2Paths ID2PathList
// into key-value for kv store
func (s *Server) prepareField2PathMeta(segID UniqueID, field2Paths *datapb.ID2PathList) (result map[string]string, err error) {
if field2Paths == nil {
return nil, errNilID2Paths
}
result = make(map[string]string, len(field2Paths.GetPaths()))
fieldID := field2Paths.GetID()
var key string
for _, p := range field2Paths.GetPaths() {
key, err = s.genKey(true, segID, fieldID)
if err != nil {
return nil, err
}
binlogPath := proto.MarshalTextString(&datapb.SegmentFieldBinlogMeta{
FieldID: fieldID,
BinlogPath: p,
})
result[path.Join(Params.SegmentBinlogSubPath, key)] = binlogPath
}
return result, err
}
// getFieldBinlogMeta querys field binlog meta from kv store
func (s *Server) getFieldBinlogMeta(segmentID UniqueID,
fieldID UniqueID) (metas []*datapb.SegmentFieldBinlogMeta, err error) {
prefix, err := s.genKey(false, segmentID, fieldID)
if err != nil {
return nil, err
}
_, vs, err := s.kvClient.LoadWithPrefix(path.Join(Params.SegmentBinlogSubPath, prefix))
if err != nil {
return nil, err
}
for _, blob := range vs {
m := &datapb.SegmentFieldBinlogMeta{}
if err = proto.UnmarshalText(blob, m); err != nil {
return nil, err
}
metas = append(metas, m)
}
return
}
// getSegmentBinlogMeta querys segment bin log meta from kv store
func (s *Server) getSegmentBinlogMeta(segmentID UniqueID) (metas []*datapb.SegmentFieldBinlogMeta, err error) {
prefix, err := s.genKey(false, segmentID)
if err != nil {
return nil, err
}
_, vs, err := s.kvClient.LoadWithPrefix(path.Join(Params.SegmentBinlogSubPath, prefix))
if err != nil {
return nil, err
}
for _, blob := range vs {
m := &datapb.SegmentFieldBinlogMeta{}
if err = proto.UnmarshalText(blob, m); err != nil {
return nil, err
}
metas = append(metas, m)
}
return
}
// GetVChanPositions get vchannel latest postitions with provided dml channel names
func (s *Server) GetVChanPositions(vchans []vchannel) ([]*datapb.VchannelInfo, error) {
if s.kvClient == nil {
return nil, errNilKvClient
}
pairs := make([]*datapb.VchannelInfo, 0, len(vchans))
for _, vchan := range vchans {
segments := s.meta.GetSegmentsByChannel(vchan.DmlChannel)
flushedSegmentIDs := make([]UniqueID, 0)
unflushed := make([]*datapb.SegmentInfo, 0)
var seekPosition *internalpb.MsgPosition
var useUnflushedPosition bool
for _, s := range segments {
if s.State == commonpb.SegmentState_Flushing || s.State == commonpb.SegmentState_Flushed {
flushedSegmentIDs = append(flushedSegmentIDs, s.ID)
if seekPosition == nil || (!useUnflushedPosition && s.DmlPosition.Timestamp > seekPosition.Timestamp) {
seekPosition = s.DmlPosition
}
continue
}
if s.DmlPosition == nil {
continue
}
unflushed = append(unflushed, s)
if seekPosition == nil || !useUnflushedPosition || s.DmlPosition.Timestamp < seekPosition.Timestamp {
useUnflushedPosition = true
seekPosition = s.DmlPosition
}
}
pairs = append(pairs, &datapb.VchannelInfo{
CollectionID: vchan.CollectionID,
ChannelName: vchan.DmlChannel,
SeekPosition: seekPosition,
UnflushedSegments: unflushed,
FlushedSegments: flushedSegmentIDs,
})
}
return pairs, nil
}
func zeroPos(name string) internalpb.MsgPosition {
return internalpb.MsgPosition{
ChannelName: name,
}
}