func PhysicalRestore()

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
}