From b0de37d09f2303ffcba1584e24ff4074443f1674 Mon Sep 17 00:00:00 2001 From: ymmt Date: Wed, 6 Sep 2023 06:28:56 +0000 Subject: [PATCH] backup: PITR did not work sometimes A bug in RestoreManager.FindNearestDump caused the bug. Fixes #563. --- backup/restore.go | 19 +++++++++++++------ backup/restore_test.go | 10 +++++++++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/backup/restore.go b/backup/restore.go index 9332c9644..f988b3b06 100644 --- a/backup/restore.go +++ b/backup/restore.go @@ -138,7 +138,6 @@ func (rm *RestoreManager) Restore(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to list object keys: %w", err) } - sort.Strings(keys) dumpKey, binlogKey, backupTime := rm.FindNearestDump(keys) if dumpKey == "" { @@ -195,16 +194,19 @@ func (rm *RestoreManager) Restore(ctx context.Context) error { return nil } +// FindNearestDump finds the nearest dump file and binlog file to the restore point. +// `keys` are object keys for the restoring instance. They need not be sorted. func (rm *RestoreManager) FindNearestDump(keys []string) (string, string, time.Time) { + sort.Strings(keys) + var nearest time.Time var nearestDump, nearestBinlog string for _, key := range keys { - if strings.HasSuffix(key, constants.BinlogFilename) { - nearestBinlog = key - continue - } - if !strings.HasSuffix(key, constants.DumpFilename) { + isBinlog := strings.HasSuffix(key, constants.BinlogFilename) + isDump := strings.HasSuffix(key, constants.DumpFilename) + if !isBinlog && !isDump { + rm.log.Info("skipping garbage", "key", key) continue } @@ -217,6 +219,11 @@ func (rm *RestoreManager) FindNearestDump(keys []string) (string, string, time.T break } + if isBinlog { + nearestBinlog = key + continue + } + nearestDump = key nearest = bkt if path.Dir(nearestDump) != path.Dir(nearestBinlog) { diff --git a/backup/restore_test.go b/backup/restore_test.go index d5959bc5b..2b627fc19 100644 --- a/backup/restore_test.go +++ b/backup/restore_test.go @@ -15,6 +15,10 @@ func TestFindNearestDump(t *testing.T) { "moco/test/test/garbage", "moco/test/test/20210526000000/dump.tar", // invalid "moco/test/test/20210526-000000/dump.tar", + "moco/test/test/20210527-000000/dump.tar", + "moco/test/test/20210527-000000/binlog.tar.zst", + "moco/test/test/20210528-000000/dump.tar", + "moco/test/test/20210528-000000/binlog.tar.zst", } testCases := []struct { @@ -25,7 +29,7 @@ func TestFindNearestDump(t *testing.T) { expectBinlog string expectTime time.Time }{ - {"latest", time.Date(2021, time.May, 26, 0, 0, 0, 0, time.UTC), + {"exact", time.Date(2021, time.May, 26, 0, 0, 0, 0, time.UTC), "moco/test/test/20210526-000000/dump.tar", "", time.Date(2021, time.May, 26, 0, 0, 0, 0, time.UTC)}, {"up-to-date", time.Date(2021, time.May, 26, 1, 0, 0, 0, time.UTC), "moco/test/test/20210526-000000/dump.tar", "", time.Date(2021, time.May, 26, 0, 0, 0, 0, time.UTC)}, @@ -35,6 +39,10 @@ func TestFindNearestDump(t *testing.T) { "moco/test/test/20210525-112233/dump.tar", "moco/test/test/20210525-112233/binlog.tar.zst", time.Date(2021, time.May, 25, 11, 22, 33, 0, time.UTC)}, {"not-found", time.Date(2021, time.May, 24, 0, 0, 0, 0, time.UTC), "", "", time.Time{}}, + {"#563", time.Date(2021, time.May, 27, 12, 0, 0, 0, time.UTC), + "moco/test/test/20210527-000000/dump.tar", "moco/test/test/20210527-000000/binlog.tar.zst", + time.Date(2021, time.May, 27, 0, 0, 0, 0, time.UTC), + }, } for _, tc := range testCases {