diff --git a/go/test/endtoend/backup/vtctlbackup/backup_utils.go b/go/test/endtoend/backup/vtctlbackup/backup_utils.go index cf264c612cf..dc785ed992d 100644 --- a/go/test/endtoend/backup/vtctlbackup/backup_utils.go +++ b/go/test/endtoend/backup/vtctlbackup/backup_utils.go @@ -446,7 +446,7 @@ func primaryBackup(t *testing.T) { // Restore the older/first backup -- using the timestamp we saved -- on the original primary tablet (primary) err = localCluster.VtctlclientProcess.ExecuteCommand("RestoreFromBackup", "--", "--backup_timestamp", firstBackupTimestamp, primary.Alias) require.Nil(t, err) - + verifyRestorePositionAndTimeStats(t, primary.VttabletProcess.GetVars()) // Re-init the shard -- making the original primary tablet (primary) primary again -- for subsequent tests err = localCluster.VtctlclientProcess.InitShardPrimary(keyspaceName, shardName, cell, primary.TabletUID) require.Nil(t, err) @@ -1048,3 +1048,16 @@ func TestReplicaRestoreToPos(t *testing.T, restoreToPos mysql.Position, expectEr } require.NoErrorf(t, err, "output: %v", output) } + +func verifyRestorePositionAndTimeStats(t *testing.T, vars map[string]any) { + require.Contains(t, vars, "RestoredBackupTime") + backupTime := vars["RestoredBackupTime"].(string) + require.NotEqual(t, "", backupTime) + + require.Contains(t, vars, "RestorePosition") + backupPosition := vars["RestorePosition"].(string) + require.NotEqual(t, "", backupPosition) + rp, err := mysql.DecodePosition(backupPosition) + require.NoError(t, err) + require.False(t, rp.IsZero()) +} diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 2c6cb3b82dc..a784bfcc658 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -22,6 +22,8 @@ import ( "io" "time" + "vitess.io/vitess/go/stats" + "github.com/spf13/pflag" "vitess.io/vitess/go/mysql" @@ -52,8 +54,16 @@ var ( restoreFromBackupTsStr string restoreConcurrency = 4 waitForBackupInterval time.Duration + + statsRestoredBackupTime *stats.String + statsRestoreBackupPosition *stats.String ) +func init() { + statsRestoredBackupTime = stats.NewString("RestoredBackupTime") + statsRestoreBackupPosition = stats.NewString("RestorePosition") +} + func registerRestoreFlags(fs *pflag.FlagSet) { fs.BoolVar(&restoreFromBackup, "restore_from_backup", restoreFromBackup, "(init restore parameter) will check BackupStorage for a recent backup at startup and start there") fs.StringVar(&restoreFromBackupTsStr, "restore_from_backup_ts", restoreFromBackupTsStr, "(init restore parameter) if set, restore the latest backup taken at or before this timestamp. Example: '2021-04-29.133050'") @@ -225,6 +235,11 @@ func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.L var backupManifest *mysqlctl.BackupManifest for { backupManifest, err = mysqlctl.Restore(ctx, params) + if backupManifest != nil { + statsRestoreBackupPosition.Set(mysql.EncodePosition(backupManifest.Position)) + statsRestoredBackupTime.Set(backupManifest.BackupTime) + } + params.Logger.Infof("Restore: got a restore manifest: %v, err=%v, waitForBackupInterval=%v", backupManifest, err, waitForBackupInterval) if waitForBackupInterval == 0 { break