in oracle/pkg/agents/backup/restore.go [80:176]
func PhysicalRestore(ctx context.Context, params *Params) (*lropb.Operation, error) {
klog.InfoS("oracle/PhysicalRestore", "params", params)
var channels string
for i := 1; i <= int(params.DOP); i++ {
channels += fmt.Sprintf(allocateChannel, i)
}
klog.InfoS("oracle/PhysicalRestore", "channels", channels)
backupDir := consts.DefaultRMANDir
if params.LocalPath != "" {
backupDir = params.LocalPath
}
if params.GCSPath != "" {
backupDir = consts.RMANStagingDir
downloadReq := &dbdpb.DownloadDirectoryFromGCSRequest{
GcsPath: params.GCSPath,
LocalPath: backupDir,
}
klog.InfoS("oracle/PhysicalRestore", "restore from gcs, downloadReq", downloadReq)
if _, err := params.Client.DownloadDirectoryFromGCS(ctx, downloadReq); err != nil {
return nil, fmt.Errorf("PhysicalRestore: failed to download rman backup from GCS bucket %s", err)
}
}
klog.InfoS("oracle/PhysicalRestore", "backupDir", backupDir)
resp, err := params.Client.ReadDir(ctx, &dbdpb.ReadDirRequest{
Path: backupDir,
Recursive: true,
})
if err != nil {
return nil, fmt.Errorf("PhysicalRestore: failed to read backup dir: %v", err)
}
// Files stored in default format:
// "nnsnf" is used to locate spfile backup piece;
// "ncnnf" is used to locate control file backup piece;
latestSpfileBackup, err := findLatestBackupPiece(resp, "nnsnf")
if err != nil {
return nil, fmt.Errorf("PhysicalRestore: failed to find latest spfile backup piece: %v", err)
}
latestControlfileBackup, err := findLatestBackupPiece(resp, "ncnnf")
if err != nil {
return nil, fmt.Errorf("PhysicalRestore: failed to find latest control file backup piece: %v", err)
}
// Delete spfile and datafiles.
if err := deleteFilesForRestore(ctx, params.Client, params.CDBName); err != nil {
klog.ErrorS(err, "PhysicalRestore: failed to delete the spfile and datafiles before restore")
}
// Ensures all required dirs are exist.
if err := createDirsForRestore(ctx, params.Client, params.CDBName); err != nil {
return nil, fmt.Errorf("PhysicalRestore: failed to createDirsForRestore: %v", err)
}
spfileLoc := filepath.Join(
fmt.Sprintf(consts.ConfigDir, consts.DataMount, params.CDBName),
fmt.Sprintf("spfile%s.ora", params.CDBName),
)
restoreStmt := fmt.Sprintf(restoreStmtTemplate, spfileLoc, latestSpfileBackup, latestControlfileBackup, params.BackupIncarnation, channels, params.Incarnation)
req := &dbdpb.PhysicalRestoreAsyncRequest{
SyncRequest: &dbdpb.PhysicalRestoreRequest{
RestoreStatement: restoreStmt,
LatestRecoverableScnQuery: maxSCNquery,
RecoverStatementTemplate: recoverStmtTemplate,
},
LroInput: &dbdpb.LROInput{OperationId: params.OperationID},
}
if params.EndTime != nil || params.EndSCN != 0 {
req = &dbdpb.PhysicalRestoreAsyncRequest{
SyncRequest: &dbdpb.PhysicalRestoreRequest{
RestoreStatement: restoreStmt,
RecoverStatementTemplate: recoverStmtTemplate,
PitrRestoreInput: &dbdpb.PhysicalRestoreRequest_PITRRestoreInput{
LogGcsPath: params.LogGcsDir,
Incarnation: params.Incarnation,
StartTime: params.StartTime,
EndTime: params.EndTime,
StartScn: params.StartSCN,
EndScn: params.EndSCN,
},
},
LroInput: &dbdpb.LROInput{OperationId: params.OperationID},
}
}
operation, err := params.Client.PhysicalRestoreAsync(ctx, req)
if err != nil {
return nil, fmt.Errorf("oracle/PhysicalRestore: failed to create database restore request: %v", err)
}
return operation, nil
}