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'ing binlog from %v", pos) s, err := c.syncer.StartSync(pos) if err != nil { return errors.Errorf("Failed starting sync at %v: %v", pos, err) } originalTimeout := time.Second timeout := originalTimeout forceSavePos := false for { ev, err := s.GetEventTimeout(timeout) if err != nil && err != replication.ErrGetEventTimeout { return errors.Trace(err) } else if err == replication.ErrGetEventTimeout { if timeout == 2*originalTimeout { log.Debugf("Flushing event handlers since sync has gone idle") if err := c.flushEventHandlers(); err != nil { log.Warnf("Error occurred during flush: %v", err) } } timeout = 2 * timeout continue } timeout = time.Second //next binlog pos pos.Pos = ev.Header.LogPos forceSavePos = false log.Debugf("Syncing %v", ev) switch e := ev.Event.(type) { case *replication.RotateEvent: c.flushEventHandlers() 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("Error handling rows event: %v", err) return errors.Trace(err) } case *replication.QueryEvent: if err = c.handleQueryEvent(ev); err != nil { log.Errorf("Error handling rows event: %v", err) return errors.Trace(err) } default: log.Debugf("Ignored event: %+v", e) } c.master.Update(pos.Name, pos.Pos) c.master.Save(forceSavePos) } return nil }