Skip to content

Commit 6b9a75d

Browse files
committed
Fix wait option for physical restore
When using --wait option during the physical restore, pbm cli waits status done and cleanup activity to be finished.
1 parent 7db2fe1 commit 6b9a75d

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

cmd/pbm/restore.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,7 @@ func waitRestore(
234234
return errors.Wrap(err, "get storage")
235235
}
236236

237-
tk := time.NewTicker(time.Second * 1)
238-
defer tk.Stop()
239-
240237
var rmeta *restore.RestoreMeta
241-
242238
getMeta := restore.GetRestoreMeta
243239
if m.Type == defs.PhysicalBackup || m.Type == defs.IncrementalBackup {
244240
getMeta = func(_ context.Context, _ connect.Client, name string) (*restore.RestoreMeta, error) {
@@ -251,6 +247,10 @@ func waitRestore(
251247
if m.Type != defs.LogicalBackup {
252248
frameSec = 60 * 3
253249
}
250+
251+
tk := time.NewTicker(time.Second * 1)
252+
defer tk.Stop()
253+
254254
for range tk.C {
255255
fmt.Print(".")
256256
rmeta, err = getMeta(ctx, conn, m.Name)
@@ -263,6 +263,19 @@ func waitRestore(
263263

264264
switch rmeta.Status {
265265
case status, defs.StatusDone, defs.StatusPartlyDone:
266+
if m.Type == defs.PhysicalBackup || m.Type == defs.IncrementalBackup {
267+
alive, err := restore.IsCleanupHbAlive(m.Name, stg, tskew)
268+
if err != nil {
269+
if errors.Is(err, storage.ErrNotExist) ||
270+
errors.Is(err, storage.ErrEmpty) {
271+
continue
272+
}
273+
return errors.Wrap(err, "checking cleanup hb")
274+
}
275+
if alive {
276+
continue
277+
}
278+
}
266279
return nil
267280
case defs.StatusError:
268281
return restoreFailedError{fmt.Sprintf("operation failed with: %s", rmeta.Error)}

pbm/restore/storage.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ package restore
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"io"
7+
"path"
68
"path/filepath"
79
"strconv"
810
"strings"
11+
"time"
912

1013
"github.com/mongodb/mongo-tools/common/db"
1114

@@ -276,3 +279,36 @@ func parsePhysRestoreCond(stg storage.Storage, fname, restoreName string) (*Cond
276279
}
277280
return &cond, nil
278281
}
282+
283+
// IsCleanupHbAlive returns true if cleanup hb is active on any agent during physical restore.
284+
// It reads timestamp from file and takes into account potential time skew.
285+
// When hb excides timeout, means that cleanup is done, false is returned.
286+
func IsCleanupHbAlive(restoreName string, stg storage.Storage, tskew int64) (bool, error) {
287+
file := path.Join(defs.PhysRestoresDir, restoreName, fmt.Sprintf("cluster.%s", syncHbCleanupSuffix))
288+
_, err := stg.FileStat(file)
289+
if err != nil {
290+
return false, errors.Wrap(err, "get cleanup hb file stat")
291+
}
292+
293+
f, err := stg.SourceReader(file)
294+
if err != nil {
295+
return false, errors.Wrap(err, "get cleanup hb file")
296+
}
297+
298+
b, err := io.ReadAll(f)
299+
if err != nil {
300+
return false, errors.Wrap(err, "read cleanup hb content")
301+
}
302+
303+
t, err := strconv.ParseInt(strings.TrimSpace(string(b)), 10, 0)
304+
if err != nil {
305+
return false, errors.Wrap(err, "cleanup hb decode")
306+
}
307+
308+
ctime := time.Now().Unix() + tskew
309+
if t+int64(hbCleanupFrame.Seconds())+hbCleanupTimeout < ctime {
310+
return false, nil
311+
}
312+
313+
return true, nil
314+
}

0 commit comments

Comments
 (0)