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