未验证 提交 390fad4e 编写于 作者: C congqixia 提交者: GitHub

Fix LatestPosition option conflict with earliest patch (#10907)

Signed-off-by: NCongqi Xia <congqi.xia@zilliz.com>
上级 b4182587
...@@ -312,54 +312,54 @@ func (s *Server) initMeta() error { ...@@ -312,54 +312,54 @@ func (s *Server) initMeta() error {
func (s *Server) startServerLoop() { func (s *Server) startServerLoop() {
s.serverLoopCtx, s.serverLoopCancel = context.WithCancel(s.ctx) s.serverLoopCtx, s.serverLoopCancel = context.WithCancel(s.ctx)
s.serverLoopWg.Add(4) s.serverLoopWg.Add(4)
go s.startStatsChannel(s.serverLoopCtx) s.startStatsChannel(s.serverLoopCtx)
go s.startDataNodeTtLoop(s.serverLoopCtx) s.startDataNodeTtLoop(s.serverLoopCtx)
go s.startWatchService(s.serverLoopCtx) s.startWatchService(s.serverLoopCtx)
go s.startFlushLoop(s.serverLoopCtx) s.startFlushLoop(s.serverLoopCtx)
go s.session.LivenessCheck(s.serverLoopCtx, func() { go s.session.LivenessCheck(s.serverLoopCtx, func() {
log.Fatal("Data Coord disconnected from etcd, process will exit", zap.Int64("Server Id", s.session.ServerID)) log.Fatal("Data Coord disconnected from etcd, process will exit", zap.Int64("Server Id", s.session.ServerID))
}) })
} }
func (s *Server) startStatsChannel(ctx context.Context) { func (s *Server) startStatsChannel(ctx context.Context) {
defer logutil.LogPanic()
defer s.serverLoopWg.Done()
statsStream, _ := s.msFactory.NewMsgStream(ctx) statsStream, _ := s.msFactory.NewMsgStream(ctx)
statsStream.AsConsumer([]string{Params.StatisticsChannelName}, Params.DataCoordSubscriptionName) statsStream.AsConsumer([]string{Params.StatisticsChannelName}, Params.DataCoordSubscriptionName)
log.Debug("dataCoord create stats channel consumer", log.Debug("dataCoord create stats channel consumer",
zap.String("channelName", Params.StatisticsChannelName), zap.String("channelName", Params.StatisticsChannelName),
zap.String("descriptionName", Params.DataCoordSubscriptionName)) zap.String("descriptionName", Params.DataCoordSubscriptionName))
statsStream.Start() statsStream.Start()
defer statsStream.Close() go func() {
for { defer logutil.LogPanic()
select { defer s.serverLoopWg.Done()
case <-ctx.Done(): defer statsStream.Close()
log.Debug("stats channel shutdown") for {
return select {
default: case <-ctx.Done():
} log.Debug("stats channel shutdown")
msgPack := statsStream.Consume() return
if msgPack == nil { default:
log.Debug("receive nil stats msg, shutdown stats channel") }
return msgPack := statsStream.Consume()
} if msgPack == nil {
for _, msg := range msgPack.Msgs { log.Debug("receive nil stats msg, shutdown stats channel")
if msg.Type() != commonpb.MsgType_SegmentStatistics { return
log.Warn("receive unknown msg from segment statistics channel",
zap.Stringer("msgType", msg.Type()))
continue
} }
ssMsg := msg.(*msgstream.SegmentStatisticsMsg) for _, msg := range msgPack.Msgs {
for _, stat := range ssMsg.SegStats { if msg.Type() != commonpb.MsgType_SegmentStatistics {
s.meta.SetCurrentRows(stat.GetSegmentID(), stat.GetNumRows()) log.Warn("receive unknown msg from segment statistics channel",
zap.Stringer("msgType", msg.Type()))
continue
}
ssMsg := msg.(*msgstream.SegmentStatisticsMsg)
for _, stat := range ssMsg.SegStats {
s.meta.SetCurrentRows(stat.GetSegmentID(), stat.GetNumRows())
}
} }
} }
} }()
} }
func (s *Server) startDataNodeTtLoop(ctx context.Context) { func (s *Server) startDataNodeTtLoop(ctx context.Context) {
defer logutil.LogPanic()
defer s.serverLoopWg.Done()
ttMsgStream, err := s.msFactory.NewMsgStream(ctx) ttMsgStream, err := s.msFactory.NewMsgStream(ctx)
if err != nil { if err != nil {
log.Error("new msg stream failed", zap.Error(err)) log.Error("new msg stream failed", zap.Error(err))
...@@ -371,97 +371,103 @@ func (s *Server) startDataNodeTtLoop(ctx context.Context) { ...@@ -371,97 +371,103 @@ func (s *Server) startDataNodeTtLoop(ctx context.Context) {
zap.String("timeTickChannelName", Params.TimeTickChannelName), zap.String("timeTickChannelName", Params.TimeTickChannelName),
zap.String("subscriptionName", Params.DataCoordSubscriptionName)) zap.String("subscriptionName", Params.DataCoordSubscriptionName))
ttMsgStream.Start() ttMsgStream.Start()
defer ttMsgStream.Close()
var checker *LongTermChecker go func() {
if enableTtChecker { var checker *LongTermChecker
checker = NewLongTermChecker(ctx, ttCheckerName, ttMaxInterval, ttCheckerWarnMsg) if enableTtChecker {
checker.Start() checker = NewLongTermChecker(ctx, ttCheckerName, ttMaxInterval, ttCheckerWarnMsg)
defer checker.Stop() checker.Start()
} defer checker.Stop()
for {
select {
case <-ctx.Done():
log.Debug("data node tt loop shutdown")
return
default:
}
msgPack := ttMsgStream.Consume()
if msgPack == nil {
log.Debug("receive nil tt msg, shutdown tt channel")
return
} }
for _, msg := range msgPack.Msgs { defer logutil.LogPanic()
if msg.Type() != commonpb.MsgType_DataNodeTt { defer s.serverLoopWg.Done()
log.Warn("receive unexpected msg type from tt channel", defer ttMsgStream.Close()
zap.Stringer("msgType", msg.Type())) for {
continue select {
case <-ctx.Done():
log.Debug("data node tt loop shutdown")
return
default:
} }
ttMsg := msg.(*msgstream.DataNodeTtMsg) msgPack := ttMsgStream.Consume()
if enableTtChecker { if msgPack == nil {
checker.Check() log.Debug("receive nil tt msg, shutdown tt channel")
return
} }
for _, msg := range msgPack.Msgs {
if msg.Type() != commonpb.MsgType_DataNodeTt {
log.Warn("receive unexpected msg type from tt channel",
zap.Stringer("msgType", msg.Type()))
continue
}
ttMsg := msg.(*msgstream.DataNodeTtMsg)
if enableTtChecker {
checker.Check()
}
ch := ttMsg.ChannelName ch := ttMsg.ChannelName
ts := ttMsg.Timestamp ts := ttMsg.Timestamp
if err := s.segmentManager.ExpireAllocations(ch, ts); err != nil { if err := s.segmentManager.ExpireAllocations(ch, ts); err != nil {
log.Warn("failed to expire allocations", zap.Error(err)) log.Warn("failed to expire allocations", zap.Error(err))
continue continue
} }
physical, _ := tsoutil.ParseTS(ts) physical, _ := tsoutil.ParseTS(ts)
if time.Since(physical).Minutes() > 1 { if time.Since(physical).Minutes() > 1 {
// if lag behind, log every 1 mins about // if lag behind, log every 1 mins about
log.RatedWarn(60.0, "Time tick lag behind for more than 1 minutes", zap.String("channel", ch), zap.Time("tt", physical)) log.RatedWarn(60.0, "Time tick lag behind for more than 1 minutes", zap.String("channel", ch), zap.Time("tt", physical))
} }
segments, err := s.segmentManager.GetFlushableSegments(ctx, ch, ts) segments, err := s.segmentManager.GetFlushableSegments(ctx, ch, ts)
if err != nil { if err != nil {
log.Warn("get flushable segments failed", zap.Error(err)) log.Warn("get flushable segments failed", zap.Error(err))
continue continue
} }
staleSegments := s.meta.SelectSegments(func(info *SegmentInfo) bool { staleSegments := s.meta.SelectSegments(func(info *SegmentInfo) bool {
return !info.lastFlushTime.IsZero() && time.Since(info.lastFlushTime).Minutes() >= segmentTimedFlushDuration return !info.lastFlushTime.IsZero() && time.Since(info.lastFlushTime).Minutes() >= segmentTimedFlushDuration
}) })
if len(segments)+len(staleSegments) == 0 { if len(segments)+len(staleSegments) == 0 {
continue
}
log.Debug("flush segments", zap.Int64s("segmentIDs", segments), zap.Int("markSegments count", len(staleSegments)))
segmentInfos := make([]*datapb.SegmentInfo, 0, len(segments))
for _, id := range segments {
sInfo := s.meta.GetSegment(id)
if sInfo == nil {
log.Error("get segment from meta error", zap.Int64("id", id),
zap.Error(err))
continue continue
} }
segmentInfos = append(segmentInfos, sInfo.SegmentInfo) log.Debug("flush segments", zap.Int64s("segmentIDs", segments), zap.Int("markSegments count", len(staleSegments)))
s.meta.SetLastFlushTime(id, time.Now()) segmentInfos := make([]*datapb.SegmentInfo, 0, len(segments))
} for _, id := range segments {
markSegments := make([]*datapb.SegmentInfo, 0, len(staleSegments)) sInfo := s.meta.GetSegment(id)
for _, segment := range staleSegments { if sInfo == nil {
for _, fSeg := range segmentInfos { log.Error("get segment from meta error", zap.Int64("id", id),
// check segment needs flush first zap.Error(err))
if segment.GetID() == fSeg.GetID() {
continue continue
} }
segmentInfos = append(segmentInfos, sInfo.SegmentInfo)
s.meta.SetLastFlushTime(id, time.Now())
}
markSegments := make([]*datapb.SegmentInfo, 0, len(staleSegments))
for _, segment := range staleSegments {
for _, fSeg := range segmentInfos {
// check segment needs flush first
if segment.GetID() == fSeg.GetID() {
continue
}
}
markSegments = append(markSegments, segment.SegmentInfo)
s.meta.SetLastFlushTime(segment.GetID(), time.Now())
}
if len(segmentInfos)+len(markSegments) > 0 {
s.cluster.Flush(s.ctx, segmentInfos, markSegments)
} }
markSegments = append(markSegments, segment.SegmentInfo)
s.meta.SetLastFlushTime(segment.GetID(), time.Now())
}
if len(segmentInfos)+len(markSegments) > 0 {
s.cluster.Flush(s.ctx, segmentInfos, markSegments)
} }
s.helper.eventAfterHandleDataNodeTt()
} }
s.helper.eventAfterHandleDataNodeTt() }()
}
} }
//go:norace // start a goroutine wto watch services
// fix datarace in unittest
// startWatchService will only be invoked at start procedure
// otherwise, remove the annotation and add atomic protection
func (s *Server) startWatchService(ctx context.Context) { func (s *Server) startWatchService(ctx context.Context) {
go s.watchService(ctx)
}
// watchService watchs services
func (s *Server) watchService(ctx context.Context) {
defer logutil.LogPanic() defer logutil.LogPanic()
defer s.serverLoopWg.Done() defer s.serverLoopWg.Done()
for { for {
...@@ -484,6 +490,7 @@ func (s *Server) startWatchService(ctx context.Context) { ...@@ -484,6 +490,7 @@ func (s *Server) startWatchService(ctx context.Context) {
} }
} }
} }
} }
// handles session events - DataNodes Add/Del // handles session events - DataNodes Add/Del
...@@ -527,22 +534,24 @@ func (s *Server) handleSessionEvent(ctx context.Context, event *sessionutil.Sess ...@@ -527,22 +534,24 @@ func (s *Server) handleSessionEvent(ctx context.Context, event *sessionutil.Sess
} }
func (s *Server) startFlushLoop(ctx context.Context) { func (s *Server) startFlushLoop(ctx context.Context) {
defer logutil.LogPanic() go func() {
defer s.serverLoopWg.Done() defer logutil.LogPanic()
ctx2, cancel := context.WithCancel(ctx) defer s.serverLoopWg.Done()
defer cancel() ctx2, cancel := context.WithCancel(ctx)
// send `Flushing` segments defer cancel()
go s.handleFlushingSegments(ctx2) // send `Flushing` segments
for { go s.handleFlushingSegments(ctx2)
select { for {
case <-ctx.Done(): select {
log.Debug("flush loop shutdown") case <-ctx.Done():
return log.Debug("flush loop shutdown")
case segmentID := <-s.flushCh: return
//Ignore return error case segmentID := <-s.flushCh:
_ = s.postFlush(ctx, segmentID) //Ignore return error
_ = s.postFlush(ctx, segmentID)
}
} }
} }()
} }
// post function after flush is done // post function after flush is done
......
...@@ -592,7 +592,7 @@ func TestService_WatchServices(t *testing.T) { ...@@ -592,7 +592,7 @@ func TestService_WatchServices(t *testing.T) {
signal := make(chan struct{}, 1) signal := make(chan struct{}, 1)
go func() { go func() {
svr.startWatchService(context.Background()) svr.watchService(context.Background())
flag = true flag = true
signal <- struct{}{} signal <- struct{}{}
}() }()
...@@ -609,7 +609,7 @@ func TestService_WatchServices(t *testing.T) { ...@@ -609,7 +609,7 @@ func TestService_WatchServices(t *testing.T) {
svr.serverLoopWg.Add(1) svr.serverLoopWg.Add(1)
go func() { go func() {
svr.startWatchService(ctx) svr.watchService(ctx)
flag = true flag = true
signal <- struct{}{} signal <- struct{}{}
}() }()
......
...@@ -67,9 +67,12 @@ func (pc *pulsarClient) Subscribe(options ConsumerOptions) (Consumer, error) { ...@@ -67,9 +67,12 @@ func (pc *pulsarClient) Subscribe(options ConsumerOptions) (Consumer, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
//consumer.Seek(pulsar.EarliestMessageID())
//consumer.SeekByTime(time.Unix(0, 0))
pConsumer := &pulsarConsumer{c: consumer, closeCh: make(chan struct{})} pConsumer := &pulsarConsumer{c: consumer, closeCh: make(chan struct{})}
// prevent seek to earliest patch applied when using latest position options
if options.SubscriptionInitialPosition == SubscriptionPositionLatest {
pConsumer.hasSeek = true
}
return pConsumer, nil return pConsumer, nil
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册