Skip to content

Commit

Permalink
Restore windows need to work off end-times (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
davissp14 authored Jul 6, 2024
1 parent 135085d commit 7c8cd32
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 35 deletions.
43 changes: 11 additions & 32 deletions internal/flypg/barman_restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,64 +211,43 @@ func (*BarmanRestore) resolveBackupFromTime(backupList BackupList, restoreStr st
return "", fmt.Errorf("no backups found")
}

var restoreTime time.Time

// Parse the restore string
restoreTime, err := time.Parse(time.RFC3339, restoreStr)
if err != nil {
return "", fmt.Errorf("failed to parse restore time: %s", err)
}

latestBackupID := ""
latestStartTime := time.Time{}

earliestBackupID := ""
earliestEndTime := time.Time{}
var lastBackupID string
var lastBackupTime time.Time

// This is the layout presented by barman
layout := "Mon Jan 2 15:04:05 2006"

for _, backup := range backupList.Backups {
// Skip backups that that failed or are in progress
// TODO - This shouldn't be needed, but will keep it around until we can improve tests.
if backup.Status != "DONE" {
continue
}

// Parse the backup start time
startTime, err := time.Parse(layout, backup.StartTime)
if err != nil {
return "", fmt.Errorf("failed to parse backup start time: %s", err)
}
// Parse the backup start time
// Parse the backup end time
endTime, err := time.Parse(layout, backup.EndTime)
if err != nil {
return "", fmt.Errorf("failed to parse backup end time: %s", err)
}
// Check if the restore time falls within the backup window
if restoreTime.After(startTime) && restoreTime.Before(endTime) {
return backup.BackupID, nil
}

// Track the latest and earliest backups in case the restore time is outside
// the available backup windows
if latestBackupID == "" || startTime.After(latestStartTime) {
latestBackupID = backup.BackupID
latestStartTime = startTime
// If the last backup ID is empty or the restore time is after the last backup time, update the last backup ID.
if lastBackupID == "" || restoreTime.After(endTime) {
lastBackupID = backup.BackupID
lastBackupTime = endTime
}

if earliestBackupID == "" || endTime.Before(earliestEndTime) {
earliestBackupID = backup.BackupID
earliestEndTime = endTime
// If the restore time is after the backup end time, we can short-circuit and return the last backup.
if endTime.After(lastBackupTime) {
return lastBackupID, nil
}
}

// if the restore time is before the earliest backup, restore the earliest backup
if restoreTime.Before(earliestEndTime) {
return earliestBackupID, nil
}

return latestBackupID, nil
return lastBackupID, nil
}

func waitOnRecovery(ctx context.Context, privateIP string) error {
Expand Down
6 changes: 3 additions & 3 deletions internal/flypg/barman_restore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ func TestResolveBackupTarget(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}

t.Run("resolve-earliest-backup-target", func(t *testing.T) {
backupID, err := restore.resolveBackupFromTime(list, "2024-06-25T19:44:12-00:00")
t.Run("resolve-oldest-target", func(t *testing.T) {
backupID, err := restore.resolveBackupFromTime(list, "2024-06-25T19:40:18-00:00")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand All @@ -351,7 +351,7 @@ func TestResolveBackupTarget(t *testing.T) {
})

t.Run("resolve-backup-within-second-window", func(t *testing.T) {
backupID, err := restore.resolveBackupFromTime(list, "2024-06-26T17:25:15-00:00")
backupID, err := restore.resolveBackupFromTime(list, "2024-06-26T17:29:15-00:00")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
Expand Down

0 comments on commit 7c8cd32

Please sign in to comment.