Skip to content

Commit 866edb9

Browse files
committed
on reconnect in the middle of transaction make sure to read interrupted transaction from the beginning
this is another stab at issues go-mysql-org#414 and go-mysql-org#416
1 parent f52d30c commit 866edb9

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

replication/binlogsyncer.go

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ type BinlogSyncer struct {
120120

121121
nextPos Position
122122

123-
gset GTIDSet
123+
prevGset, currGset GTIDSet
124124

125125
running bool
126126

@@ -376,7 +376,7 @@ func (b *BinlogSyncer) StartSync(pos Position) (*BinlogStreamer, error) {
376376
func (b *BinlogSyncer) StartSyncGTID(gset GTIDSet) (*BinlogStreamer, error) {
377377
log.Infof("begin to sync binlog from GTID set %s", gset)
378378

379-
b.gset = gset
379+
b.prevGset = gset
380380

381381
b.m.Lock()
382382
defer b.m.Unlock()
@@ -569,9 +569,9 @@ func (b *BinlogSyncer) retrySync() error {
569569

570570
b.parser.Reset()
571571

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 {
572+
if b.prevGset != nil {
573+
log.Infof("begin to re-sync from %s", b.prevGset.String())
574+
if err := b.prepareSyncGTID(b.prevGset); err != nil {
575575
return errors.Trace(err)
576576
}
577577
} else {
@@ -643,7 +643,7 @@ func (b *BinlogSyncer) onStream(s *BinlogStreamer) {
643643
log.Error(err)
644644
// we meet connection error, should re-connect again with
645645
// last nextPos or nextGTID we got.
646-
if len(b.nextPos.Name) == 0 && b.gset == nil {
646+
if len(b.nextPos.Name) == 0 && b.prevGset == nil {
647647
// we can't get the correct position, close.
648648
s.closeWithError(err)
649649
return
@@ -733,33 +733,53 @@ func (b *BinlogSyncer) parseEvent(s *BinlogStreamer, data []byte) error {
733733
// Some events like FormatDescriptionEvent return 0, ignore.
734734
b.nextPos.Pos = e.Header.LogPos
735735
}
736+
737+
getCurrentGtidSet := func() GTIDSet {
738+
if b.currGset == nil {
739+
return nil
740+
}
741+
return b.currGset.Clone()
742+
}
743+
744+
advanceCurrentGtidSet := func(gtid string) error {
745+
if b.currGset == nil {
746+
b.currGset = b.prevGset.Clone()
747+
}
748+
prev := b.currGset.Clone()
749+
err := b.currGset.Update(gtid)
750+
if err == nil {
751+
b.prevGset = prev
752+
}
753+
return err
754+
}
755+
736756
switch event := e.Event.(type) {
737757
case *RotateEvent:
738758
b.nextPos.Name = string(event.NextLogName)
739759
b.nextPos.Pos = uint32(event.Position)
740760
log.Infof("rotate to %s", b.nextPos)
741761
case *GTIDEvent:
742-
if b.gset == nil {
762+
if b.prevGset == nil {
743763
break
744764
}
745765
u, _ := uuid.FromBytes(event.SID)
746-
err := b.gset.Update(fmt.Sprintf("%s:%d", u.String(), event.GNO))
766+
err := advanceCurrentGtidSet(fmt.Sprintf("%s:%d", u.String(), event.GNO))
747767
if err != nil {
748768
return errors.Trace(err)
749769
}
750770
case *MariadbGTIDEvent:
751-
if b.gset == nil {
771+
if b.prevGset == nil {
752772
break
753773
}
754774
GTID := event.GTID
755-
err := b.gset.Update(fmt.Sprintf("%d-%d-%d", GTID.DomainID, GTID.ServerID, GTID.SequenceNumber))
775+
err := advanceCurrentGtidSet(fmt.Sprintf("%d-%d-%d", GTID.DomainID, GTID.ServerID, GTID.SequenceNumber))
756776
if err != nil {
757777
return errors.Trace(err)
758778
}
759779
case *XIDEvent:
760-
event.GSet = b.getGtidSet()
780+
event.GSet = getCurrentGtidSet()
761781
case *QueryEvent:
762-
event.GSet = b.getGtidSet()
782+
event.GSet = getCurrentGtidSet()
763783
}
764784

765785
needStop := false
@@ -783,13 +803,6 @@ func (b *BinlogSyncer) parseEvent(s *BinlogStreamer, data []byte) error {
783803
return nil
784804
}
785805

786-
func (b *BinlogSyncer) getGtidSet() GTIDSet {
787-
if b.gset == nil {
788-
return nil
789-
}
790-
return b.gset.Clone()
791-
}
792-
793806
// LastConnectionID returns last connectionID.
794807
func (b *BinlogSyncer) LastConnectionID() uint32 {
795808
return b.lastConnectionID

0 commit comments

Comments
 (0)