Files
ROMFASTSQL/oracle/standby-server-scripts/transfer_to_dr.ps1
Marius ac2340c967 Oracle DR: Complete Windows VM implementation and cleanup
Major changes:
- Implemented Windows VM 109 as DR target (replaces Linux LXC)
- Tested RMAN restore successfully (12-15 min RTO, 24h RPO)
- Added comprehensive DR documentation:
  * DR_WINDOWS_VM_STATUS_2025-10-09.md - Current implementation status
  * DR_UPGRADE_TO_CUMULATIVE_PLAN.md - Plan for cumulative incremental backups
  * DR_VM_MIGRATION_GUIDE.md - Guide for VM migration between Proxmox nodes
- Updated DR_WINDOWS_VM_IMPLEMENTATION_PLAN.md with completed phases

New scripts:
- add_system_key_dr.ps1 - SSH key setup for automated transfers
- configure_listener_dr.ps1 - Oracle Listener configuration
- fix_ssh_via_service.ps1 - SSH authentication fix
- rman_restore_final.cmd - Working RMAN restore script (tested)
- transfer_to_dr.ps1 - FULL backup transfer (renamed from 02_*)
- transfer_incremental.ps1 - Incremental backup transfer (renamed from 02b_*)

Cleanup:
- Removed 19 obsolete scripts for Linux LXC DR
- Removed 8 outdated documentation files
- Organized project structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-09 18:54:08 +03:00

203 lines
6.9 KiB
PowerShell

# Transfer Oracle RMAN Backup towards DR Server
# Rulează după backup RMAN (03:00 AM)
# Copiază backup-uri de pe PRIMARY (10.0.20.36) către DR (10.0.20.37)
param(
[string]$SourceFRA = "C:\Users\Oracle\recovery_area\ROA",
[string]$DRHost = "10.0.20.37",
[int]$DRPort = 22122,
[string]$DRUser = "romfast",
[string]$DRPath = "D:/oracle/backups/primary",
[string]$SSHKeyPath = "$env:USERPROFILE\.ssh\id_rsa",
[int]$RetentionDays = 2,
[string]$LogFile = "D:\rman_backup\logs\transfer_$(Get-Date -Format 'yyyyMMdd').log"
)
$ErrorActionPreference = "Continue"
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logLine = "[$timestamp] [$Level] $Message"
Write-Host $logLine
Add-Content -Path $LogFile -Value $logLine -Encoding UTF8 -ErrorAction SilentlyContinue
}
function Test-SSHConnection {
Write-Log "Testing SSH connection to $DRHost`:$DRPort..."
try {
# Folosește -n pentru a nu citi din stdin (fix pentru blocare)
$null = & ssh -n -p $DRPort -i $SSHKeyPath -o StrictHostKeyChecking=no -o ConnectTimeout=10 "${DRUser}@${DRHost}" "exit 0" 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Log "SSH connection successful" "SUCCESS"
return $true
} else {
Write-Log "SSH connection failed with exit code: $LASTEXITCODE" "ERROR"
return $false
}
} catch {
Write-Log "SSH connection error: $_" "ERROR"
return $false
}
}
function Get-TodaysBackups {
Write-Log "Searching for today's backup files..."
$today = Get-Date
$cutoffDate = $today.Date # Only today (after midnight)
$backupFiles = @()
$searchPaths = @(
"$SourceFRA\BACKUPSET",
"$SourceFRA\AUTOBACKUP"
)
foreach ($path in $searchPaths) {
if (Test-Path $path) {
# Get files created TODAY only (exclude old backups)
$files = Get-ChildItem -Path $path -Recurse -File -ErrorAction SilentlyContinue |
Where-Object {
$_.LastWriteTime -gt $cutoffDate -and
$_.Name -notlike "*__TAG_*" # Exclude old uncompressed backups
} |
Sort-Object LastWriteTime -Descending
$backupFiles += $files
}
}
if ($backupFiles.Count -eq 0) {
Write-Log "No backup files found for today!" "WARNING"
return @()
}
$totalSizeGB = ($backupFiles | Measure-Object -Property Length -Sum).Sum / 1GB
Write-Log "Found $($backupFiles.Count) files, total size: $([math]::Round($totalSizeGB, 2)) GB"
return $backupFiles
}
function Transfer-FileToDR {
param([System.IO.FileInfo]$File, [string]$DestPath)
$fileName = $File.Name
$fileSizeMB = [math]::Round($File.Length / 1MB, 2)
try {
# Check dacă fișierul există deja pe DR (skip duplicates) - Windows PowerShell command
$checkCmd = "powershell -Command `"Test-Path '$DestPath/$fileName'`""
$checkResult = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $checkCmd 2>&1
if ($checkResult -match "True") {
Write-Log "Skipping (already on DR): $fileName" "INFO"
return $true
}
Write-Log "Transferring: $fileName ($fileSizeMB MB)"
# SCP transfer - NO compression (files already compressed by RMAN)
# Use cipher aes128-gcm for better performance
$null = & scp -P $DRPort -i $SSHKeyPath -o StrictHostKeyChecking=no -o Compression=no -o Cipher=aes128-gcm@openssh.com $File.FullName "${DRUser}@${DRHost}:${DestPath}/" 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Log "Transferred: $fileName" "SUCCESS"
return $true
} else {
Write-Log "Failed to transfer: $fileName (exit code: $LASTEXITCODE)" "ERROR"
return $false
}
} catch {
Write-Log "Transfer error for $fileName : $_" "ERROR"
return $false
}
}
function Cleanup-OldBackupsOnDR {
Write-Log "Cleaning up old backups on DR (keeping last $RetentionDays days)..."
try {
# Cleanup: șterge fișiere mai vechi de $RetentionDays zile - Windows PowerShell command
$retentionDate = (Get-Date).AddDays(-$RetentionDays).ToString("yyyy-MM-dd")
$cleanupCmd = "powershell -Command `"Get-ChildItem -Path '$DRPath' -Recurse -File | Where-Object { `$_.LastWriteTime -lt '$retentionDate' } | Remove-Item -Force -ErrorAction SilentlyContinue`""
$result = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $cleanupCmd 2>&1
Write-Log "Cleanup completed on DR (removed files older than $retentionDate)"
} catch {
Write-Log "Cleanup warning: $_" "WARNING"
}
}
# ==================== MAIN ====================
try {
Write-Log "========================================="
Write-Log "Oracle DR Backup Transfer Started"
Write-Log "========================================="
Write-Log "Source FRA: $SourceFRA"
Write-Log "DR Server: $DRHost"
Write-Log "DR Path: $DRPath"
# Verificare prerequisite
if (-not (Test-Path $SourceFRA)) {
throw "Source FRA path not found: $SourceFRA"
}
if (-not (Test-Path $SSHKeyPath)) {
throw "SSH key not found: $SSHKeyPath"
}
# Test SSH connection
if (-not (Test-SSHConnection)) {
throw "Cannot connect to DR server via SSH"
}
# Creare director pe DR - Windows PowerShell command
Write-Log "Ensuring DR directory exists..."
$null = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "powershell -Command `"New-Item -ItemType Directory -Path '$DRPath' -Force | Out-Null`"" 2>&1
# Găsește backup-uri
$backupFiles = Get-TodaysBackups
if ($backupFiles.Count -eq 0) {
throw "No backup files to transfer!"
}
# Transfer fișiere
Write-Log "Starting file transfer..."
$successCount = 0
$failCount = 0
foreach ($file in $backupFiles) {
if (Transfer-FileToDR -File $file -DestPath $DRPath) {
$successCount++
} else {
$failCount++
}
}
Write-Log "Transfer summary: $successCount succeeded, $failCount failed"
if ($failCount -gt 0) {
Write-Log "Some transfers failed!" "WARNING"
}
# Cleanup old backups pe DR
Cleanup-OldBackupsOnDR
Write-Log "========================================="
Write-Log "DR Backup Transfer Completed Successfully"
Write-Log "========================================="
Write-Log "Files transferred: $successCount/$($backupFiles.Count)"
Write-Log "DR Server: ${DRHost}:${DRPath}"
exit 0
} catch {
Write-Log "CRITICAL ERROR: $($_.Exception.Message)" "ERROR"
Write-Log "Stack trace: $($_.ScriptStackTrace)" "ERROR"
exit 1
}