@@ -185,13 +185,13 @@ func (s *Scorch) ForceMerge(ctx context.Context,
185185 mo * mergeplan.MergePlanOptions ) error {
186186 // check whether force merge is already under processing
187187 s .rootLock .Lock ()
188- if s .stats .TotFileMergeForceOpsStarted >
189- s .stats .TotFileMergeForceOpsCompleted {
188+ if atomic . LoadUint64 ( & s .stats .TotFileMergeForceOpsStarted ) >
189+ atomic . LoadUint64 ( & s .stats .TotFileMergeForceOpsCompleted ) {
190190 s .rootLock .Unlock ()
191191 return fmt .Errorf ("force merge already in progress" )
192192 }
193193
194- s .stats .TotFileMergeForceOpsStarted ++
194+ atomic . AddUint64 ( & s .stats .TotFileMergeForceOpsStarted , 1 )
195195 s .rootLock .Unlock ()
196196
197197 if mo != nil {
@@ -296,6 +296,7 @@ type mergeBatch struct {
296296 newID uint64
297297 newDocNums [][]uint64
298298 newFilename string
299+ newTime uint64
299300}
300301
301302// planMergeAtSnapshot plans and executes the merge operations for a given snapshot
@@ -397,6 +398,7 @@ func (s *Scorch) planMergeAtSnapshot(ctrlMsg *mergerCtrl, ourSnapshot *IndexSnap
397398 newID : newSegmentID ,
398399 newDocNums : nil ,
399400 newFilename : zapFileName (newSegmentID ),
401+ newTime : 0 ,
400402 }
401403 mergeBatches [batchID ] = batch
402404
@@ -428,17 +430,16 @@ func (s *Scorch) planMergeAtSnapshot(ctrlMsg *mergerCtrl, ourSnapshot *IndexSnap
428430 s .markIneligibleForRemoval (batch .newFilename )
429431 path := s .path + string (os .PathSeparator ) + batch .newFilename
430432
433+ prevBytesReadTotal := cumulateBytesRead (batch .segments )
431434 fileMergeZapStartTime := time .Now ()
432435 atomic .AddUint64 (& s .stats .TotFileMergeZapBeg , 1 )
433- prevBytesReadTotal := cumulateBytesRead (batch .segments )
434436 batch .newDocNums , _ , err = s .segPlugin .MergeUsing (batch .segments , batch .drops , path ,
435437 cw .cancelCh , s , s .segmentConfig )
436438 atomic .AddUint64 (& s .stats .TotFileMergeZapEnd , 1 )
437-
438- fileMergeZapTime := uint64 (time .Since (fileMergeZapStartTime ))
439- atomic .AddUint64 (& s .stats .TotFileMergeZapTime , fileMergeZapTime )
440- if atomic .LoadUint64 (& s .stats .MaxFileMergeZapTime ) < fileMergeZapTime {
441- atomic .StoreUint64 (& s .stats .MaxFileMergeZapTime , fileMergeZapTime )
439+ batch .newTime = uint64 (time .Since (fileMergeZapStartTime ))
440+ atomic .AddUint64 (& s .stats .TotFileMergeZapTime , batch .newTime )
441+ if atomic .LoadUint64 (& s .stats .MaxFileMergeZapTime ) < batch .newTime {
442+ atomic .StoreUint64 (& s .stats .MaxFileMergeZapTime , batch .newTime )
442443 }
443444 if err != nil {
444445 atomic .AddUint64 (& s .stats .TotFileMergePlanTasksErr , 1 )
@@ -473,11 +474,12 @@ func (s *Scorch) planMergeAtSnapshot(ctrlMsg *mergerCtrl, ourSnapshot *IndexSnap
473474 }
474475
475476 sm := & segmentMerge {
476- id : newSegmentIDs ,
477- new : newSegments ,
477+ newSegmentIDs : newSegmentIDs ,
478+ newSegments : newSegments ,
478479 mergedSegHistory : mergedSegHistory ,
479480 notifyCh : make (chan * mergeTaskIntroStatus ),
480481 mmaped : 1 ,
482+ fileMerge : true ,
481483 }
482484
483485 s .fireEvent (EventKindMergeTaskIntroductionStart , 0 )
@@ -532,11 +534,12 @@ type mergedSegmentHistory struct {
532534}
533535
534536type segmentMerge struct {
535- id []uint64
536- new []segment.Segment
537+ newSegmentIDs []uint64
538+ newSegments []segment.Segment
537539 mergedSegHistory map [uint64 ]* mergedSegmentHistory
538540 notifyCh chan * mergeTaskIntroStatus
539541 mmaped uint32
542+ fileMerge bool
540543}
541544
542545func cumulateBytesRead (sbs []segment.Segment ) uint64 {
@@ -577,6 +580,7 @@ func (s *Scorch) mergeAndPersistInMemorySegments(flushes []*flushable, po *persi
577580 var err error
578581 defer func () {
579582 if err != nil {
583+ atomic .AddUint64 (& s .stats .TotMemMergeErr , 1 )
580584 errM .Lock ()
581585 errs = append (errs , err )
582586 errM .Unlock ()
@@ -597,10 +601,10 @@ func (s *Scorch) mergeAndPersistInMemorySegments(flushes []*flushable, po *persi
597601 newID : newSegmentID ,
598602 newDocNums : nil ,
599603 newFilename : zapFileName (newSegmentID ),
604+ newTime : 0 ,
600605 }
601606 mergeBatches [batchID ] = batch
602607
603- atomic .AddUint64 (& numMergedSegments , uint64 (len (flush .sbsBatch )))
604608 s .markIneligibleForRemoval (batch .newFilename )
605609 path := s .path + string (os .PathSeparator ) + batch .newFilename
606610
@@ -609,26 +613,32 @@ func (s *Scorch) mergeAndPersistInMemorySegments(flushes []*flushable, po *persi
609613 batch .newDocNums , _ , err = s .segPlugin .MergeUsing (batch .segments , batch .drops , path ,
610614 s .closeCh , s , s .segmentConfig )
611615 atomic .AddUint64 (& s .stats .TotMemMergeZapEnd , 1 )
612- memMergeZapTime := uint64 (time .Since (memMergeZapStartTime ))
613- atomic .AddUint64 (& s .stats .TotMemMergeZapTime , memMergeZapTime )
614- if atomic .LoadUint64 (& s .stats .MaxMemMergeZapTime ) < memMergeZapTime {
615- atomic .StoreUint64 (& s .stats .MaxMemMergeZapTime , memMergeZapTime )
616- }
616+ batch .newTime = uint64 (time .Since (memMergeZapStartTime ))
617+ atomic .AddUint64 (& s .stats .TotMemMergeZapTime , batch .newTime )
617618 if err != nil {
618- atomic .AddUint64 (& s .stats .TotMemMergeErr , 1 )
619619 return
620620 }
621-
622621 batch .new , err = s .segPlugin .OpenUsing (path , s .segmentConfig )
623622 if err != nil {
624- atomic .AddUint64 (& s .stats .TotMemMergeErr , 1 )
625623 return
626624 }
625+ atomic .AddUint64 (& numMergedSegments , uint64 (len (batch .segments )))
627626 }(batchID )
628627 }
629628 wg .Wait ()
630629 close (sem )
631630
631+ var maxZapTime uint64
632+ for _ , batch := range mergeBatches {
633+ if batch .newTime > maxZapTime {
634+ maxZapTime = batch .newTime
635+ }
636+ }
637+ if maxZapTime > atomic .LoadUint64 (& s .stats .MaxMemMergeZapTime ) {
638+ atomic .StoreUint64 (& s .stats .MaxMemMergeZapTime , maxZapTime )
639+ }
640+ atomic .AddUint64 (& s .stats .TotMemMergeSegments , numMergedSegments )
641+
632642 if len (errs ) > 0 {
633643 var errf error
634644 numClosed := 0
@@ -666,22 +676,31 @@ func (s *Scorch) mergeAndPersistInMemorySegments(flushes []*flushable, po *persi
666676 }
667677
668678 sm := & segmentMerge {
669- id : newSegmentIDs ,
670- new : newSegments ,
679+ newSegmentIDs : newSegmentIDs ,
680+ newSegments : newSegments ,
671681 mergedSegHistory : mergedSegHistory ,
672682 notifyCh : make (chan * mergeTaskIntroStatus ),
673683 mmaped : 1 ,
684+ fileMerge : false ,
674685 }
675686
676687 select {
677688 case <- s .closeCh :
678689 err = segment .ErrClosed
679690 return nil , nil , err
680691 case s .merges <- sm :
692+ atomic .AddUint64 (& s .stats .TotMemMergeIntroductions , uint64 (numBatches ))
681693 }
682694
695+ introStartTime := time .Now ()
683696 // blockingly wait for the introduction to complete
684697 introStatus := <- sm .notifyCh
698+ introTime := uint64 (time .Since (introStartTime ))
699+ atomic .AddUint64 (& s .stats .TotMemMergeZapIntroductionTime , introTime )
700+ if atomic .LoadUint64 (& s .stats .MaxMemMergeZapIntroductionTime ) < introTime {
701+ atomic .StoreUint64 (& s .stats .MaxMemMergeZapIntroductionTime , introTime )
702+ }
703+ atomic .AddUint64 (& s .stats .TotMemMergeIntroductionsDone , uint64 (numBatches ))
685704 introducedSnapshot := introStatus .indexSnapshot
686705 introducedSegmentIDs := make (map [uint64 ]struct {}, numBatches )
687706 for batchID , skipped := range introStatus .skipped {
@@ -703,8 +722,6 @@ func (s *Scorch) mergeAndPersistInMemorySegments(flushes []*flushable, po *persi
703722 return nil , nil , nil
704723 }
705724
706- atomic .AddUint64 (& s .stats .TotMemMergeSegments , numMergedSegments )
707-
708725 return introducedSnapshot , introducedSegmentIDs , nil
709726}
710727
0 commit comments