@@ -118,7 +118,7 @@ type BinlogSyncer struct {
118
118
119
119
nextPos Position
120
120
121
- gset GTIDSet
121
+ prevGset , currGset GTIDSet
122
122
123
123
running bool
124
124
@@ -380,7 +380,7 @@ func (b *BinlogSyncer) StartSync(pos Position) (*BinlogStreamer, error) {
380
380
func (b * BinlogSyncer ) StartSyncGTID (gset GTIDSet ) (* BinlogStreamer , error ) {
381
381
log .Infof ("begin to sync binlog from GTID set %s" , gset )
382
382
383
- b .gset = gset
383
+ b .prevGset = gset
384
384
385
385
b .m .Lock ()
386
386
defer b .m .Unlock ()
@@ -389,6 +389,10 @@ func (b *BinlogSyncer) StartSyncGTID(gset GTIDSet) (*BinlogStreamer, error) {
389
389
return nil , errors .Trace (errSyncRunning )
390
390
}
391
391
392
+ // establishing network connection here and will start getting binlog events from "gset + 1", thus until first
393
+ // MariadbGTIDEvent/GTIDEvent event is received - we effectively do not have a "current GTID"
394
+ b .currGset = nil
395
+
392
396
if err := b .prepare (); err != nil {
393
397
return nil , errors .Trace (err )
394
398
}
@@ -573,9 +577,14 @@ func (b *BinlogSyncer) retrySync() error {
573
577
574
578
b .parser .Reset ()
575
579
576
- if b .gset != nil {
577
- log .Infof ("begin to re-sync from %s" , b .gset .String ())
578
- if err := b .prepareSyncGTID (b .gset ); err != nil {
580
+ if b .prevGset != nil {
581
+ msg := fmt .Sprintf ("begin to re-sync from %s" , b .prevGset .String ())
582
+ if b .currGset != nil {
583
+ msg = fmt .Sprintf ("%v (last read GTID=%v)" , msg , b .currGset )
584
+ }
585
+ log .Infof (msg )
586
+
587
+ if err := b .prepareSyncGTID (b .prevGset ); err != nil {
579
588
return errors .Trace (err )
580
589
}
581
590
} else {
@@ -608,6 +617,10 @@ func (b *BinlogSyncer) prepareSyncPos(pos Position) error {
608
617
func (b * BinlogSyncer ) prepareSyncGTID (gset GTIDSet ) error {
609
618
var err error
610
619
620
+ // re establishing network connection here and will start getting binlog events from "gset + 1", thus until first
621
+ // MariadbGTIDEvent/GTIDEvent event is received - we effectively do not have a "current GTID"
622
+ b .currGset = nil
623
+
611
624
if err = b .prepare (); err != nil {
612
625
return errors .Trace (err )
613
626
}
@@ -644,7 +657,7 @@ func (b *BinlogSyncer) onStream(s *BinlogStreamer) {
644
657
645
658
// we meet connection error, should re-connect again with
646
659
// last nextPos or nextGTID we got.
647
- if len (b .nextPos .Name ) == 0 && b .gset == nil {
660
+ if len (b .nextPos .Name ) == 0 && b .prevGset == nil {
648
661
// we can't get the correct position, close.
649
662
s .closeWithError (err )
650
663
return
@@ -732,33 +745,53 @@ func (b *BinlogSyncer) parseEvent(spanContext opentracing.SpanContext, s *Binlog
732
745
// Some events like FormatDescriptionEvent return 0, ignore.
733
746
b .nextPos .Pos = e .Header .LogPos
734
747
}
748
+
749
+ getCurrentGtidSet := func () GTIDSet {
750
+ if b .currGset == nil {
751
+ return nil
752
+ }
753
+ return b .currGset .Clone ()
754
+ }
755
+
756
+ advanceCurrentGtidSet := func (gtid string ) error {
757
+ if b .currGset == nil {
758
+ b .currGset = b .prevGset .Clone ()
759
+ }
760
+ prev := b .currGset .Clone ()
761
+ err := b .currGset .Update (gtid )
762
+ if err == nil {
763
+ b .prevGset = prev
764
+ }
765
+ return err
766
+ }
767
+
735
768
switch event := e .Event .(type ) {
736
769
case * RotateEvent :
737
770
b .nextPos .Name = string (event .NextLogName )
738
771
b .nextPos .Pos = uint32 (event .Position )
739
772
log .Infof ("rotate to %s" , b .nextPos )
740
773
case * GTIDEvent :
741
- if b .gset == nil {
774
+ if b .prevGset == nil {
742
775
break
743
776
}
744
777
u , _ := uuid .FromBytes (event .SID )
745
- err := b . gset . Update (fmt .Sprintf ("%s:%d" , u .String (), event .GNO ))
778
+ err := advanceCurrentGtidSet (fmt .Sprintf ("%s:%d" , u .String (), event .GNO ))
746
779
if err != nil {
747
780
return errors .Trace (err )
748
781
}
749
782
case * MariadbGTIDEvent :
750
- if b .gset == nil {
783
+ if b .prevGset == nil {
751
784
break
752
785
}
753
786
GTID := event .GTID
754
- err := b . gset . Update (fmt .Sprintf ("%d-%d-%d" , GTID .DomainID , GTID .ServerID , GTID .SequenceNumber ))
787
+ err := advanceCurrentGtidSet (fmt .Sprintf ("%d-%d-%d" , GTID .DomainID , GTID .ServerID , GTID .SequenceNumber ))
755
788
if err != nil {
756
789
return errors .Trace (err )
757
790
}
758
791
case * XIDEvent :
759
- event .GSet = b . getGtidSet ()
792
+ event .GSet = getCurrentGtidSet ()
760
793
case * QueryEvent :
761
- event .GSet = b . getGtidSet ()
794
+ event .GSet = getCurrentGtidSet ()
762
795
}
763
796
764
797
needStop := false
@@ -782,13 +815,6 @@ func (b *BinlogSyncer) parseEvent(spanContext opentracing.SpanContext, s *Binlog
782
815
return nil
783
816
}
784
817
785
- func (b * BinlogSyncer ) getGtidSet () GTIDSet {
786
- if b .gset == nil {
787
- return nil
788
- }
789
- return b .gset .Clone ()
790
- }
791
-
792
818
// LastConnectionID returns last connectionID.
793
819
func (b * BinlogSyncer ) LastConnectionID () uint32 {
794
820
return b .lastConnectionID
0 commit comments