# Transfer Oracle INCREMENTAL Backup towards DR Server # Rulează după backup incremental (14:30) # Mai simplu decât scriptul full - doar transferă fișierele noi param( [string]$SourceFRA = "C:\Users\Oracle\recovery_area\ROA", [string]$DRHost = "10.0.20.202", [int]$DRPort = 22, [string]$DRUser = "root", [string]$DRPath = "/mnt/pve/oracle-backups/ROA/autobackup", [string]$SSHKeyPath = "$env:USERPROFILE\.ssh\id_rsa", [string]$LogFile = "D:\rman_backup\logs\transfer_incr_$(Get-Date -Format 'yyyyMMdd_HHmm').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 Get-IncrementalBackups { Write-Log "Searching for incremental backup files created in last 2 hours..." $cutoffTime = (Get-Date).AddHours(-2) $backupFiles = @() # Caută în BACKUPSET, AUTOBACKUP $searchPaths = @( "$SourceFRA\BACKUPSET", "$SourceFRA\AUTOBACKUP" ) foreach ($path in $searchPaths) { if (Test-Path $path) { $files = Get-ChildItem -Path $path -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt $cutoffTime -and $_.Name -match '\.(BKP|bkp)$' } $backupFiles += $files } } return $backupFiles } function Cleanup-OldBackupsOnDR { param([int]$RetentionDays = 2) Write-Log "Cleaning up old backups on DR (keeping last $RetentionDays days)..." try { # Count fișiere înainte de cleanup $countBefore = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "find '$DRPath' -name '*.BKP' -type f | wc -l" 2>&1 Write-Log "Backups before cleanup: $countBefore" # Cleanup: șterge fișiere mai vechi de $RetentionDays zile # -mtime +N înseamnă "mai vechi de N zile", deci pentru a păstra RetentionDays zile, folosim +($RetentionDays - 1) $mtimeDays = $RetentionDays - 1 $cleanupCmd = "find '$DRPath' -name '*.BKP' -type f -mtime +$mtimeDays -delete 2>&1" $result = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $cleanupCmd 2>&1 if ($LASTEXITCODE -ne 0) { Write-Log "Cleanup warning: $result" "WARNING" } # Count fișiere după cleanup $countAfter = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "find '$DRPath' -name '*.BKP' -type f | wc -l" 2>&1 $deleted = [int]$countBefore - [int]$countAfter Write-Log "Cleanup completed: Deleted $deleted old backup files, $countAfter remaining" } catch { Write-Log "Cleanup error: $_" "WARNING" } } try { Write-Log "=========================================" Write-Log "Oracle INCREMENTAL Backup Transfer Started" Write-Log "=========================================" Write-Log "Source FRA: $SourceFRA" Write-Log "DR Server: $DRHost" # Test SSH connection Write-Log "Testing SSH connection to $DRHost`:$DRPort..." $null = & ssh -n -p $DRPort -i $SSHKeyPath -o StrictHostKeyChecking=no -o ConnectTimeout=10 "${DRUser}@${DRHost}" "exit 0" 2>&1 if ($LASTEXITCODE -ne 0) { throw "SSH connection failed" } Write-Log "SSH connection OK" "SUCCESS" # Găsește backup-uri incrementale $backupFiles = Get-IncrementalBackups if ($backupFiles.Count -eq 0) { Write-Log "⚠️ No incremental backup files found (this might be normal if backup didn't run yet)" "WARNING" exit 0 } $totalSizeGB = ($backupFiles | Measure-Object -Property Length -Sum).Sum / 1GB Write-Log "Found $($backupFiles.Count) incremental files, total size: $([math]::Round($totalSizeGB, 2)) GB" # Transfer fișiere Write-Log "Starting file transfer..." $successCount = 0 $failCount = 0 foreach ($file in $backupFiles) { $fileName = $file.Name $fileSizeMB = [math]::Round($file.Length / 1MB, 2) # Check dacă fișierul există deja pe DR (skip duplicates) - Linux bash command $checkCmd = "test -f '$DRPath/$fileName' && echo 'True' || echo 'False'" $checkResult = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $checkCmd 2>&1 if ($checkResult -match "True") { Write-Log "Skipping (already on DR): $fileName" "INFO" $successCount++ continue } Write-Log "Transferring: $fileName ($fileSizeMB MB)" # SCP optimized: no compression (already compressed), fast cipher $null = & scp -P $DRPort -i $SSHKeyPath -o StrictHostKeyChecking=no -o Compression=no -o Cipher=aes128-gcm@openssh.com ` $file.FullName ` "${DRUser}@${DRHost}:${DRPath}/$fileName" 2>&1 if ($LASTEXITCODE -eq 0) { Write-Log "Transferred: $fileName" "SUCCESS" $successCount++ } else { Write-Log "Failed to transfer: $fileName" "ERROR" $failCount++ } } Write-Log "=========================================" Write-Log "Transfer summary: $successCount succeeded, $failCount failed" if ($failCount -gt 0) { Write-Log "⚠️ Some transfers failed!" "WARNING" exit 1 } # Cleanup old backups pe DR (keep last 2 days) Cleanup-OldBackupsOnDR -RetentionDays 2 Write-Log "=========================================" Write-Log "INCREMENTAL Backup Transfer Completed Successfully" Write-Log "=========================================" Write-Log "Files transferred: $successCount/$($backupFiles.Count)" exit 0 } catch { Write-Log "CRITICAL ERROR: $($_.Exception.Message)" "ERROR" exit 1 }