// WaitBlpPosition will wait for the filtered replication to reach at least // the provided position. func (mysqld *Mysqld) WaitBlpPosition(bp *blproto.BlpPosition, waitTimeout time.Duration) error { timeOut := time.Now().Add(waitTimeout) for { if time.Now().After(timeOut) { break } cmd := binlogplayer.QueryBlpCheckpoint(bp.Uid) qr, err := mysqld.fetchSuperQuery(cmd) if err != nil { return err } if len(qr.Rows) != 1 { return fmt.Errorf("QueryBlpCheckpoint(%v) returned unexpected row count: %v", bp.Uid, len(qr.Rows)) } var pos proto.ReplicationPosition if !qr.Rows[0][0].IsNull() { pos, err = proto.DecodeReplicationPosition(qr.Rows[0][0].String()) if err != nil { return err } } if pos.AtLeast(bp.Position) { return nil } log.Infof("Sleeping 1 second waiting for binlog replication(%v) to catch up: %v != %v", bp.Uid, pos, bp.Position) time.Sleep(1 * time.Second) } return fmt.Errorf("WaitBlpPosition(%v) timed out", bp.Uid) }
// ReadStartPosition will return the current start position and the flags for // the provided binlog player. func ReadStartPosition(dbClient VtClient, uid uint32) (*proto.BlpPosition, string, error) { selectRecovery := QueryBlpCheckpoint(uid) qr, err := dbClient.ExecuteFetch(selectRecovery, 1, true) if err != nil { return nil, "", fmt.Errorf("error %v in selecting from recovery table %v", err, selectRecovery) } if qr.RowsAffected != 1 { return nil, "", fmt.Errorf("checkpoint information not available in db for %v", uid) } pos, err := myproto.DecodeReplicationPosition(qr.Rows[0][0].String()) if err != nil { return nil, "", err } return &proto.BlpPosition{ Uid: uid, Position: pos, }, string(qr.Rows[0][1].Raw()), nil }