Files
ROMFASTSQL/oracle/standby-server-scripts/rman_restore_from_zero.ps1
Marius 3a51880c9e Oracle DR: Fix RMAN crosscheck sequence and improve error handling
- Fix CROSSCHECK BACKUP command to execute after database is mounted
- Correct CATALOG command to use recovery_area instead of F:\ path
- Add robust backup file validation with detailed error reporting
- Improve file-by-file backup copying with individual error tracking
- Enhance restore log collection for both success and failure scenarios
- Fix database verification to check OPEN_MODE instead of STATUS
- Add comprehensive directory and permissions error handling

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-10-11 10:32:49 +03:00

363 lines
12 KiB
PowerShell

# RMAN Restore Database FROM ZERO - Clean State (PowerShell)
# Backups are on F:\ (NFS mount from Proxmox host)
# Run as: Administrator
# Location: D:\oracle\scripts\rman_restore_from_zero.ps1
#
# Parameters:
# -TestMode: Skip service reconfiguration and Listener startup (for weekly DR tests)
param(
[switch]$TestMode
)
$ErrorActionPreference = "Continue"
$env:ORACLE_HOME = "C:\Users\Administrator\Downloads\WINDOWS.X64_193000_db_home"
$env:ORACLE_SID = "ROA"
$env:PATH = "$env:ORACLE_HOME\bin;$env:PATH"
Write-Host "============================================"
Write-Host "RMAN Database Restore FROM ZERO"
Write-Host "============================================"
Write-Host ""
Write-Host "Database: ROA"
Write-Host "DBID: 1363569330"
Write-Host "Backups: F:\ROA\autobackup (NFS mount from Proxmox)"
Write-Host ""
Write-Host "This script will:"
Write-Host " 1. CLEANUP: Delete any existing database files"
Write-Host " 2. RESTORE: Restore from F:\ backups"
Write-Host " 3. VERIFY: Check database is working"
Write-Host ""
# Verify F:\ mount is accessible
if (-not (Test-Path "F:\ROA\autobackup")) {
Write-Host "ERROR: F:\ROA\autobackup not accessible!" -ForegroundColor Red
Write-Host ""
Write-Host "Please verify:"
Write-Host " 1. F:\ drive is mounted: dir F:\"
Write-Host " 2. NFS mount command: mount -o rw,nolock,mtype=hard,timeout=60 10.0.20.202:/mnt/pve/oracle-backups F:"
Write-Host " 3. Proxmox host is reachable: ping 10.0.20.202"
Write-Host ""
exit 1
}
Write-Host "[OK] F:\ROA\autobackup is accessible"
Write-Host ""
# Create directories with proper permissions
try {
New-Item -ItemType Directory -Path "D:\oracle\temp" -Force -ErrorAction Stop | Out-Null
New-Item -ItemType Directory -Path "D:\oracle\logs" -Force -ErrorAction Stop | Out-Null
Write-Host "[OK] Created required directories"
} catch {
Write-Host "ERROR: Failed to create directories: $_" -ForegroundColor Red
exit 1
}
Write-Host "============================================"
Write-Host "STEP 1: CLEANUP - Delete existing database"
Write-Host "============================================"
Write-Host ""
Write-Host "Calling cleanup_database.ps1..."
Write-Host ""
# Call cleanup script with /SILENT flag
& "D:\oracle\scripts\cleanup_database.ps1" /SILENT
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host "ERROR: Cleanup failed!" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "[OK] Cleanup complete - VM is in clean state"
Write-Host ""
Write-Host "Starting restore in 2 seconds..."
Start-Sleep -Seconds 2
Write-Host "============================================"
Write-Host "STEP 2: RESTORE - Restore from F:\ backups"
Write-Host "============================================"
Write-Host ""
# Step 2.1: Create Oracle service
Write-Host "[2.1] Creating Oracle service from PFILE..."
if (-not (Test-Path "C:\Users\oracle\admin\ROA\pfile\initROA.ora")) {
Write-Host "ERROR: PFILE not found at C:\Users\oracle\admin\ROA\pfile\initROA.ora" -ForegroundColor Red
Write-Host "Cannot create Oracle service without PFILE!"
exit 1
}
& oradim -new -sid ROA -startmode auto -pfile "C:\Users\oracle\admin\ROA\pfile\initROA.ora" 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host "ERROR: Failed to create Oracle service" -ForegroundColor Red
exit 1
}
Write-Host "[OK] Oracle service created successfully (AUTOMATIC startup)"
Start-Sleep -Seconds 2
# Step 2.2: Startup NOMOUNT
Write-Host "[2.2] Starting database in NOMOUNT mode..."
$nomountSQL = @"
STARTUP NOMOUNT PFILE='C:\Users\oracle\admin\ROA\pfile\initROA.ora';
EXIT;
"@
$nomountSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host "ERROR: Failed to startup NOMOUNT" -ForegroundColor Red
exit 1
}
Write-Host "[OK] Database started in NOMOUNT mode"
Start-Sleep -Seconds 3
# Step 2.3: Copy backups and create RMAN script
Write-Host "[2.3] Preparing RMAN restore..."
$rmanScript = "D:\oracle\temp\restore_from_zero.rman"
$logFile = "D:\oracle\logs\restore_from_zero.log"
# Copy ALL backups from F:\ to recovery area
New-Item -ItemType Directory -Path "C:\Users\oracle\recovery_area\ROA\autobackup" -Force | Out-Null
Write-Host "[INFO] Copying all backups from F:\ROA\autobackup to recovery area..."
Write-Host " This may take 1-2 minutes for ~10 GB of backups..."
# Check backup files exist on F: drive before copying
try {
$backupFiles = Get-ChildItem "F:\ROA\autobackup\*.BKP" -ErrorAction Continue
} catch {
Write-Host "WARNING: Cannot enumerate backup files on F: drive - $_" -ForegroundColor Yellow
$backupFiles = @()
}
if ($backupFiles.Count -lt 2) {
Write-Host "ERROR: Insufficient backup files found on F: drive (found: $($backupFiles.Count))" -ForegroundColor Red
Write-Host " At least 2 backup files required for successful restore"
Write-Host " Checking F:\ROA\autobackup directory..."
try {
$dirCheck = Get-ChildItem "F:\ROA\autobackup" -ErrorAction Continue
Write-Host " Directory contents: $($dirCheck.Count) files"
foreach ($file in $dirCheck) {
Write-Host " $($file.Name) - $($file.Length / 1GB) GB" -ForegroundColor Gray
}
} catch {
Write-Host " Cannot access directory: $_" -ForegroundColor Red
}
exit 1
}
Write-Host "[INFO] Found $($backupFiles.Count) backup files, total size: $([math]::Round(($backupFiles | Measure-Object -Property Length -Sum).Sum / 1GB, 2)) GB"
# Copy backups with better error handling
Write-Host "[INFO] Starting backup copy operation..."
$copyErrors = @()
foreach ($backupFile in $backupFiles) {
try {
Write-Host "[INFO] Copying $($backupFile.Name)..."
Copy-Item $backupFile.FullName "C:\Users\oracle\recovery_area\ROA\autobackup\" -Force -ErrorAction Stop
Write-Host "[OK] Copied $($backupFile.Name)" -ForegroundColor Green
} catch {
Write-Host "ERROR: Failed to copy $($backupFile.Name) - $_" -ForegroundColor Red
$copyErrors += "$($backupFile.Name): $_"
}
}
if ($copyErrors.Count -gt 0) {
Write-Host "ERROR: Backup copy failed for $($copyErrors.Count) files" -ForegroundColor Red
foreach ($error in $copyErrors) {
Write-Host " $error" -ForegroundColor Red
}
exit 1
}
# Verify copied backups
try {
$copiedFiles = Get-ChildItem "C:\Users\oracle\recovery_area\ROA\autobackup\*.BKP" -ErrorAction Continue
} catch {
Write-Host "ERROR: Cannot verify copied backups - $_" -ForegroundColor Red
exit 1
}
if ($copiedFiles.Count -ne $backupFiles.Count) {
Write-Host "ERROR: Backup copy verification failed - file count mismatch" -ForegroundColor Red
Write-Host " Expected: $($backupFiles.Count), Copied: $($copiedFiles.Count)"
exit 1
}
Write-Host "[OK] All $($copiedFiles.Count) backups copied and verified to recovery area"
# Create RMAN script
$rmanContent = @"
SET DBID 1363569330;
RUN {
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
RESTORE CONTROLFILE FROM AUTOBACKUP;
RELEASE CHANNEL ch1;
}
ALTER DATABASE MOUNT;
CATALOG START WITH 'C:/USERS/ORACLE/RECOVERY_AREA/ROA/AUTOBACKUP' NOPROMPT;
CROSSCHECK BACKUP;
DELETE NOPROMPT EXPIRED BACKUP;
RUN {
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch2 DEVICE TYPE DISK;
RESTORE DATABASE;
RELEASE CHANNEL ch1;
RELEASE CHANNEL ch2;
}
RUN {
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
RECOVER DATABASE NOREDO;
RELEASE CHANNEL ch1;
}
ALTER DATABASE OPEN RESETLOGS;
DELETE NOPROMPT OBSOLETE;
EXIT;
"@
$rmanContent | Out-File -FilePath $rmanScript -Encoding ASCII
Write-Host "[OK] RMAN script created: $rmanScript"
# Step 2.4: Run RMAN restore
Write-Host "[2.4] Running RMAN restore (this will take 10-20 minutes)..."
Write-Host " Log file: $logFile"
Write-Host ""
& rman target / cmdfile=$rmanScript log=$logFile
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host "ERROR: RMAN restore failed!" -ForegroundColor Red
Write-Host "Check log: $logFile"
exit 1
}
Write-Host ""
Write-Host "[OK] RMAN restore completed successfully!"
Write-Host ""
Write-Host "============================================"
Write-Host "STEP 3: VERIFY - Check database status"
Write-Host "============================================"
Write-Host ""
Write-Host "[3.1] Verifying database..."
$verifySQL = @"
SET PAGESIZE 100 LINESIZE 200
COLUMN info FORMAT A80
SELECT 'DB_NAME: ' || NAME || ', OPEN_MODE: ' || OPEN_MODE AS info FROM V`$DATABASE;
SELECT 'INSTANCE: ' || INSTANCE_NAME || ', STATUS: ' || STATUS AS info FROM V`$INSTANCE;
SELECT 'TABLESPACES: ' || COUNT(*) AS info FROM DBA_TABLESPACES;
SELECT 'DATAFILES: ' || COUNT(*) AS info FROM DBA_DATA_FILES;
SELECT 'TABLES: ' || COUNT(*) AS info FROM DBA_TABLES WHERE OWNER NOT IN ('SYS','SYSTEM');
EXIT;
"@
$verifySQL | & sqlplus -S / as sysdba
Write-Host ""
Write-Host "[3.2] Creating SPFILE for database persistence..."
$spfileSQL = @"
CREATE SPFILE FROM PFILE='C:\Users\oracle\admin\ROA\pfile\initROA.ora';
EXIT;
"@
$spfileSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host "WARNING: Failed to create SPFILE - database may not persist after connections close" -ForegroundColor Yellow
} else {
Write-Host "[OK] SPFILE created successfully"
# Check if running in TestMode (weekly DR test)
if ($TestMode) {
Write-Host "[3.3] Running in TEST MODE - skipping service reconfiguration"
Write-Host " Database is OPEN and ready for verification"
Write-Host " Service will remain configured with PFILE (OK for testing)"
} else {
# Full configuration for standalone/production use
Write-Host "[3.3] Reconfiguring Oracle service to use SPFILE..."
# Shutdown database cleanly
Write-Host " Shutting down database temporarily..."
$shutdownSQL = @"
SHUTDOWN IMMEDIATE;
EXIT;
"@
$shutdownSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
Start-Sleep -Seconds 3
# Delete and recreate service with SPFILE
Write-Host " Recreating service with SPFILE..."
& oradim -delete -sid ROA 2>&1 | Out-Null
Start-Sleep -Seconds 2
& oradim -new -sid ROA -startmode auto -spfile 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host " WARNING: Failed to recreate service with SPFILE" -ForegroundColor Yellow
} else {
Write-Host " [OK] Service now configured with SPFILE and AUTOMATIC startup"
}
# Restart database
Write-Host " Starting database with SPFILE..."
$startupSQL = @"
STARTUP;
EXIT;
"@
$startupSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
Start-Sleep -Seconds 3
Write-Host "[OK] Database restarted with SPFILE configuration"
# Start Oracle Listener
Write-Host "[3.4] Starting Oracle Listener..."
# Set Listener service to AUTOMATIC and start it
Set-Service -Name "OracleOraDB19Home1TNSListener" -StartupType Automatic -ErrorAction SilentlyContinue
Start-Service -Name "OracleOraDB19Home1TNSListener" -ErrorAction SilentlyContinue
if ((Get-Service -Name "OracleOraDB19Home1TNSListener" -ErrorAction SilentlyContinue).Status -eq "Running") {
Write-Host "[OK] Listener started successfully"
} else {
Write-Host "WARNING: Failed to start Listener automatically, trying lsnrctl..." -ForegroundColor Yellow
& lsnrctl start 2>&1 | Out-Null
}
Start-Sleep -Seconds 2
# Register database with listener
$registerSQL = @"
ALTER SYSTEM REGISTER;
EXIT;
"@
$registerSQL | & sqlplus -S / as sysdba 2>&1 | Out-Null
Write-Host "[OK] Database registered with Listener"
}
}
Write-Host ""
Write-Host "============================================"
Write-Host "Database Restore FROM ZERO Complete!"
Write-Host "============================================"
Write-Host ""
Write-Host "Restore log: $logFile"
Write-Host ""
Write-Host "Database is OPEN and ready for testing!" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:"
Write-Host " 1. Test application connectivity"
Write-Host " 2. Verify data integrity"
Write-Host " 3. Run cleanup_database.ps1 to remove database after test"
Write-Host " 4. Shutdown DR VM to conserve resources"
Write-Host ""
exit 0