func (m *masterInfo) Pos() mysql.Position { var pos mysql.Position m.l.Lock() pos.Name = m.Name pos.Pos = m.Position m.l.Unlock() return pos }
func (c *Canal) startSyncBinlog() error { pos := mysql.Position{c.master.Name, c.master.Position} log.Infof("start sync binlog at %v", pos) s, err := c.syncer.StartSync(pos) if err != nil { return errors.Errorf("start sync replication at %v error %v", pos, err) } timeout := time.Second forceSavePos := false for { ev, err := s.GetEventTimeout(timeout) if err != nil && err != replication.ErrGetEventTimeout { return errors.Trace(err) } else if err == replication.ErrGetEventTimeout { timeout = 2 * timeout continue } timeout = time.Second //next binlog pos pos.Pos = ev.Header.LogPos forceSavePos = false switch e := ev.Event.(type) { case *replication.RotateEvent: pos.Name = string(e.NextLogName) pos.Pos = uint32(e.Position) // r.ev <- pos forceSavePos = true log.Infof("rotate binlog to %v", pos) case *replication.RowsEvent: // we only focus row based event if err = c.handleRowsEvent(ev); err != nil { log.Errorf("handle rows event error %v", err) return errors.Trace(err) } case *replication.TableMapEvent: continue default: } c.master.Update(pos.Name, pos.Pos) c.master.Save(forceSavePos) } return nil }
func (c *Canal) startSyncBinlog() error { pos := mysql.Position{c.master.Name, c.master.Position} log.Infof("start sync binlog at %v", pos) s, err := c.syncer.StartSync(pos) if err != nil { return errors.Errorf("start sync replication at %v error %v", pos, err) } timeout := time.Second forceSavePos := false for { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) ev, err := s.GetEvent(ctx) cancel() if err == context.DeadlineExceeded { timeout = 2 * timeout continue } if err != nil { return errors.Trace(err) } timeout = time.Second //next binlog pos pos.Pos = ev.Header.LogPos forceSavePos = false // We only save position with RotateEvent and XIDEvent. // For RowsEvent, we can't save the position until meeting XIDEvent // which tells the whole transaction is over. // TODO: If we meet any DDL query, we must save too. switch e := ev.Event.(type) { case *replication.RotateEvent: pos.Name = string(e.NextLogName) pos.Pos = uint32(e.Position) // r.ev <- pos forceSavePos = true log.Infof("rotate binlog to %v", pos) case *replication.RowsEvent: // we only focus row based event if err = c.handleRowsEvent(ev); err != nil { log.Errorf("handle rows event error %v", err) return errors.Trace(err) } continue case *replication.XIDEvent: // try to save the position later default: continue } c.master.Update(pos.Name, pos.Pos) c.master.Save(forceSavePos) } return nil }