Skip to content

Commit 5e8e2db

Browse files
authored
PBM-1347: save restore meta with error if retore fails before start (#1044)
1 parent 10ba619 commit 5e8e2db

File tree

3 files changed

+76
-4
lines changed

3 files changed

+76
-4
lines changed

cmd/pbm-agent/restore.go

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/percona/percona-backup-mongodb/pbm/backup"
99
"github.com/percona/percona-backup-mongodb/pbm/config"
10+
"github.com/percona/percona-backup-mongodb/pbm/connect"
1011
"github.com/percona/percona-backup-mongodb/pbm/ctrl"
1112
"github.com/percona/percona-backup-mongodb/pbm/defs"
1213
"github.com/percona/percona-backup-mongodb/pbm/errors"
@@ -93,13 +94,22 @@ func (a *Agent) Restore(ctx context.Context, r *ctrl.RestoreCmd, opid ctrl.OPID,
9394
// XXX: why is backup searched on storage?
9495
bcp, err = restore.LookupBackupMeta(ctx, a.leadConn, r.BackupName, a.brief.Me)
9596
if err != nil {
96-
l.Error("define base backup: %v", err)
97+
err1 := addRestoreMetaWithError(ctx, a.leadConn, l, opid, r, nodeInfo.SetName,
98+
"define base backup: %v", err)
99+
if err1 != nil {
100+
l.Error("failed to save meta: %v", err1)
101+
}
97102
return
98103
}
99104

100105
if !r.OplogTS.IsZero() && bcp.LastWriteTS.Compare(r.OplogTS) >= 0 {
101-
l.Error("snapshot's last write is later than the target time. " +
102-
"Try to set an earlier snapshot. Or leave the snapshot empty so PBM will choose one.")
106+
err1 := addRestoreMetaWithError(ctx, a.leadConn, l, opid, r, nodeInfo.SetName,
107+
"snapshot's last write is later than the target time. "+
108+
"Try to set an earlier snapshot. Or leave the snapshot empty "+
109+
"so PBM will choose one.")
110+
if err1 != nil {
111+
l.Error("failed to save meta: %v", err)
112+
}
103113
return
104114
}
105115
bcpType = bcp.Type
@@ -172,3 +182,46 @@ func (a *Agent) Restore(ctx context.Context, r *ctrl.RestoreCmd, opid ctrl.OPID,
172182

173183
l.Info("recovery successfully finished")
174184
}
185+
186+
func addRestoreMetaWithError(
187+
ctx context.Context,
188+
conn connect.Client,
189+
l log.LogEvent,
190+
opid ctrl.OPID,
191+
cmd *ctrl.RestoreCmd,
192+
setName string,
193+
errStr string,
194+
args ...any,
195+
) error {
196+
l.Error(errStr, args...)
197+
198+
meta := &restore.RestoreMeta{
199+
Type: defs.LogicalBackup,
200+
OPID: opid.String(),
201+
Name: cmd.Name,
202+
Backup: cmd.BackupName,
203+
PITR: int64(cmd.OplogTS.T),
204+
StartTS: time.Now().UTC().Unix(),
205+
Status: defs.StatusError,
206+
Error: errStr,
207+
Replsets: []restore.RestoreReplset{},
208+
}
209+
err := restore.SetRestoreMetaIfNotExists(ctx, conn, meta)
210+
if err != nil {
211+
return errors.Wrap(err, "write restore meta to db")
212+
}
213+
214+
rs := restore.RestoreReplset{
215+
Name: setName,
216+
StartTS: time.Now().UTC().Unix(),
217+
Status: defs.StatusError,
218+
Error: errStr,
219+
Conditions: restore.Conditions{},
220+
}
221+
err = restore.AddRestoreRSMeta(ctx, conn, cmd.Name, rs)
222+
if err != nil {
223+
return errors.Wrap(err, "write backup meta to db")
224+
}
225+
226+
return nil
227+
}

cmd/pbm/restore.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,11 @@ func doRestore(
485485
return nil, errors.Wrap(err, "get storage")
486486
}
487487

488-
fn = func(_ context.Context, _ connect.Client, name string) (*restore.RestoreMeta, error) {
488+
fn = func(ctx context.Context, conn connect.Client, name string) (*restore.RestoreMeta, error) {
489+
meta, err := restore.GetRestoreMeta(ctx, conn, name)
490+
if err == nil {
491+
return meta, nil
492+
}
489493
return restore.GetPhysRestoreMeta(name, stg, l)
490494
}
491495
startCtx, cancel = context.WithTimeout(ctx, waitPhysRestoreStart)

pbm/restore/query.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,21 @@ func SetRestoreMeta(ctx context.Context, m connect.Client, meta *RestoreMeta) er
157157
return err
158158
}
159159

160+
func SetRestoreMetaIfNotExists(ctx context.Context, m connect.Client, meta *RestoreMeta) error {
161+
meta.LastTransitionTS = meta.StartTS
162+
meta.Conditions = append(meta.Conditions, &Condition{
163+
Timestamp: meta.StartTS,
164+
Status: meta.Status,
165+
})
166+
167+
_, err := m.RestoresCollection().UpdateOne(ctx,
168+
bson.D{{"name", meta.Name}},
169+
bson.D{{"$set", meta}},
170+
options.Update().SetUpsert(true))
171+
172+
return err
173+
}
174+
160175
// GetLastRestore returns last successfully finished restore
161176
// and nil if there is no such restore yet.
162177
func GetLastRestore(ctx context.Context, m connect.Client) (*RestoreMeta, error) {

0 commit comments

Comments
 (0)