in oracle/controllers/instancecontroller/instance_controller_restore.go [430:517]
func (r *InstanceReconciler) restorePhysical(ctx context.Context, inst v1alpha1.Instance, backup *v1alpha1.Backup, req ctrl.Request, log logr.Logger) (*lropb.Operation, error) {
// Confirm that an external LB is ready.
if err := restorePhysicalPreflightCheck(ctx, r, req.Namespace, inst.Name, log); err != nil {
return nil, err
}
if backup.Spec.Backupset != nil && !*backup.Spec.Backupset {
return nil, fmt.Errorf("preflight check: located a physical backup, but in this release the auto-restore is only supported from a Backupset backup: %v", backup.Spec.Backupset)
}
if backup.Spec.Subtype != "" && backup.Spec.Subtype != "Instance" {
return nil, fmt.Errorf("preflight check: located a physical backup, but in this release the auto-restore is only supported from a Backupset taken at the Instance level: %q", backup.Spec.Subtype)
}
log.Info("preflight check for a restore from a physical backup - all DONE", "backup", backup)
dop := restoreDOP(inst.Spec.Restore.Dop, backup.Spec.Dop)
timeLimitMinutes := controllers.PhysBackupTimeLimitDefault * 3
if inst.Spec.Restore.TimeLimitMinutes != 0 {
timeLimitMinutes = time.Duration(inst.Spec.Restore.TimeLimitMinutes) * time.Minute
}
ctxRestore, cancel := context.WithTimeout(context.Background(), timeLimitMinutes)
defer cancel()
var sTime, eTime *timestamppb.Timestamp
var incarnation, backupIncarnation string
var sSCN, eSCN int64
var p v1alpha1.PITR
var err error
backupIncarnation = backup.Labels[controllers.IncarnationLabel]
incarnation = backupIncarnation
if inst.Spec.Restore.PITRRestore != nil {
// preflight check in findPITRBackupForRestore that only either SCN or timestamp must be set in PITRRestore.
if inst.Spec.Restore.PITRRestore.SCN != "" {
sSCN, err = strconv.ParseInt(backup.Annotations[controllers.SCNAnnotation], 10, 64)
if err != nil {
return nil, fmt.Errorf("PITR restore preflight check: failed to parse backup SCN %v from backup %v", err, backup)
}
eSCN, err = strconv.ParseInt(inst.Spec.Restore.PITRRestore.SCN, 10, 64)
if err != nil {
return nil, fmt.Errorf("PITR restore preflight check: failed to parse restore SCN %v from spec %v", err, inst.Spec.Restore)
}
}
if inst.Spec.Restore.PITRRestore.Timestamp != nil {
backupTimestamp, err := time.Parse(time.RFC3339, backup.Annotations[controllers.TimestampAnnotation])
if err != nil {
log.Error(err, "failed to find backup timestamp")
return nil, err
}
sTime = timestamppb.New(backupTimestamp)
eTime = timestamppb.New(inst.Spec.Restore.PITRRestore.Timestamp.Time)
}
p, err = r.findRestorePITR(ctx, &inst)
if err != nil {
return nil, err
}
incarnation = inst.Spec.Restore.PITRRestore.Incarnation
if incarnation == "" {
if inst.Spec.Restore.PITRRestore.PITRRef != nil {
// PITRRef was specified.
incarnation = p.Status.CurrentDatabaseIncarnation
} else {
incarnation = inst.Status.CurrentDatabaseIncarnation
}
}
}
restoreReq := &controllers.PhysicalRestoreRequest{
InstanceName: inst.Name,
CdbName: inst.Spec.CDBName,
Dop: dop,
LocalPath: backup.Spec.LocalPath,
GcsPath: backup.Spec.GcsPath,
LroInput: &controllers.LROInput{OperationId: lroRestoreOperationID(physicalRestore, inst)},
LogGcsPath: p.Spec.StorageURI,
Incarnation: incarnation,
BackupIncarnation: backupIncarnation,
StartTime: sTime,
EndTime: eTime,
StartScn: sSCN,
EndScn: eSCN,
}
resp, err := controllers.PhysicalRestore(ctxRestore, r, r.DatabaseClientFactory, inst.Namespace, inst.Name, *restoreReq)
if err != nil {
return nil, fmt.Errorf("failed on PhysicalRestore gRPC call: %v", err)
}
log.Info("config_agent_helpers.PhysicalRestore", "LRO", lroRestoreOperationID(physicalRestore, inst), "response", resp)
return resp, nil
}