Esempio n. 1
0
func positionCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) error {
	subFlags.Parse(args)
	if len(args) < 3 {
		return fmt.Errorf("Not enough arguments for position operation.")
	}

	pos1, err := myproto.DecodeReplicationPosition(args[1])
	if err != nil {
		return err
	}

	switch args[0] {
	case "equal":
		pos2, err := myproto.DecodeReplicationPosition(args[2])
		if err != nil {
			return err
		}
		fmt.Println(pos1.Equal(pos2))
	case "at_least":
		pos2, err := myproto.DecodeReplicationPosition(args[2])
		if err != nil {
			return err
		}
		fmt.Println(pos1.AtLeast(pos2))
	case "append":
		gtid, err := myproto.DecodeGTID(args[2])
		if err != nil {
			return err
		}
		fmt.Println(myproto.AppendGTID(pos1, gtid))
	}

	return nil
}
Esempio n. 2
0
// WaitBlpPos will wait for the filtered replication to reach at least
// the provided position.
func (mysqld *Mysqld) WaitBlpPos(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("WaitBlpPos(%v) returned unexpected row count: %v", bp.Uid, len(qr.Rows))
		}
		var gtid proto.GTID
		if !qr.Rows[0][0].IsNull() {
			gtid, err = proto.DecodeGTID(qr.Rows[0][0].String())
			if err != nil {
				return err
			}
		}
		if gtid == bp.GTIDField.Value {
			return nil
		}

		log.Infof("Sleeping 1 second waiting for binlog replication(%v) to catch up: %v != %v", bp.Uid, gtid, bp.GTIDField)
		time.Sleep(1 * time.Second)
	}

	return fmt.Errorf("WaitBlpPos(%v) timed out", bp.Uid)
}
Esempio n. 3
0
// 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)
	}
	gtid, err := myproto.DecodeGTID(qr.Rows[0][0].String())
	if err != nil {
		return nil, "", err
	}
	return &proto.BlpPosition{
		Uid:       uid,
		GTIDField: myproto.GTIDField{Value: gtid},
	}, string(qr.Rows[0][1].Raw()), nil
}
Esempio n. 4
0
// writeRecoveryPosition will write the current GTID as the recovery position
// for the next transaction.
// We will also try to get the timestamp for the transaction. Two cases:
// - we have statements, and they start with a SET TIMESTAMP that we
//   can parse: then we update transaction_timestamp in blp_checkpoint
//   with it, and set SecondsBehindMaster to now() - transaction_timestamp
// - otherwise (the statements are probably filtered out), we leave
//   transaction_timestamp alone (keeping the old value), and we don't
//   change SecondsBehindMaster
func (blp *BinlogPlayer) writeRecoveryPosition(tx *proto.BinlogTransaction) error {
	gtid, err := myproto.DecodeGTID(tx.TransactionID)
	if err != nil {
		return err
	}

	now := time.Now().Unix()

	blp.blpPos.Position = myproto.AppendGTID(blp.blpPos.Position, gtid)
	updateRecovery := UpdateBlpCheckpoint(blp.blpPos.Uid, blp.blpPos.Position, now, tx.Timestamp)

	qr, err := blp.exec(updateRecovery)
	if err != nil {
		return fmt.Errorf("Error %v in writing recovery info %v", err, updateRecovery)
	}
	if qr.RowsAffected != 1 {
		return fmt.Errorf("Cannot update blp_recovery table, affected %v rows", qr.RowsAffected)
	}
	blp.blplStats.SetLastPosition(blp.blpPos.Position)
	if tx.Timestamp != 0 {
		blp.blplStats.SecondsBehindMaster.Set(now - tx.Timestamp)
	}
	return nil
}
Esempio n. 5
0
func (rci *RowcacheInvalidator) processEvent(event *blproto.StreamEvent) error {
	defer rci.handleInvalidationError(event)
	switch event.Category {
	case "DDL":
		log.Infof("DDL invalidation: %s", event.Sql)
		rci.handleDDLEvent(event.Sql)
	case "DML":
		rci.handleDMLEvent(event)
	case "ERR":
		rci.handleUnrecognizedEvent(event.Sql)
	case "POS":
		gtid, err := myproto.DecodeGTID(event.TransactionID)
		if err != nil {
			return err
		}
		rci.AppendGTID(gtid)
	default:
		log.Errorf("unknown event: %#v", event)
		rci.qe.queryServiceStats.InternalErrors.Add("Invalidation", 1)
		return nil
	}
	rci.lagSeconds.Set(time.Now().Unix() - event.Timestamp)
	return nil
}