WIP: Oracle DR CUMULATIVE backup upgrade - Phases 1-3 completed

COMPLETED:
- Phase 1: Proxmox host storage (/mnt/pve/oracle-backups/ROA/autobackup)
- Phase 2: RMAN script already has CUMULATIVE keyword
- Phase 3: Transfer scripts updated for Proxmox host
  * transfer_incremental.ps1: 10.0.20.37:22122 → 10.0.20.202:22
  * transfer_to_dr.ps1: Same change
  * Converted Windows PowerShell to Linux bash commands
- VM 109 cleanup: ~6.4 GB freed, RMAN catalog cleaned

NEW FILES:
- copy_existing_key_to_proxmox.ps1: Setup script for SSH key
- setup_ssh_keys_for_proxmox.ps1: Alternative setup (not used)

PENDING (Next Session):
- Run copy_existing_key_to_proxmox.ps1 on PRIMARY as Administrator
- Phase 4: Modify scheduled tasks (13:00 + 18:00)
- Phase 5: Configure mount point on VM 109 (F:\ drive)
- Phase 6: Update restore script for F:\ mount
- Phase 7: Test FULL + CUMULATIVE backup and restore

DOCUMENTATION:
- DR_UPGRADE_TO_CUMULATIVE_PLAN.md: Added implementation status

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Marius
2025-10-09 22:45:32 +03:00
parent ac2340c967
commit ec77bb3ddf
8 changed files with 626 additions and 18 deletions

View File

@@ -0,0 +1,78 @@
# Copy Existing SSH Key to Proxmox
# Rulează acest script pe PRIMARY ca Administrator
#
# Acest script copiază cheia publică SSH existentă din profilul SYSTEM pe Proxmox
param(
[string]$ProxmoxHost = "10.0.20.202",
[string]$ProxmoxUser = "root"
)
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host "Copiere Cheie SSH Existentă → Proxmox DR" -ForegroundColor Cyan
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host ""
$SystemSSHDir = "C:\Windows\System32\config\systemprofile\.ssh"
$PublicKeyPath = "$SystemSSHDir\id_rsa.pub"
$PrivateKeyPath = "$SystemSSHDir\id_rsa"
# Verifică dacă cheia există
if (-not (Test-Path $PublicKeyPath)) {
Write-Host "✗ Cheia publică nu există: $PublicKeyPath" -ForegroundColor Red
Write-Host " Scriptul trebuie rulat ca Administrator!" -ForegroundColor Yellow
exit 1
}
Write-Host "✓ Cheie publică găsită: $PublicKeyPath" -ForegroundColor Green
Write-Host ""
Write-Host "→ Copiez cheia publică pe Proxmox ($ProxmoxHost)..." -ForegroundColor Yellow
Write-Host " IMPORTANT: Vei fi întrebat de parola root pentru Proxmox!" -ForegroundColor Cyan
Write-Host ""
# Metodă simplă: folosim SCP pentru a copia fișierul temporar, apoi cat
$tempFile = "C:\Windows\Temp\temp_pubkey.pub"
Copy-Item $PublicKeyPath $tempFile -Force
# Copiază fișierul pe Proxmox
& scp $tempFile "${ProxmoxUser}@${ProxmoxHost}:/tmp/temp_pubkey.pub"
if ($LASTEXITCODE -ne 0) {
Write-Host "✗ Eroare la copierea fișierului cu SCP" -ForegroundColor Red
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
exit 1
}
# Adaugă cheia în authorized_keys
& ssh "${ProxmoxUser}@${ProxmoxHost}" "mkdir -p /root/.ssh; chmod 700 /root/.ssh; cat /tmp/temp_pubkey.pub >> /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys; rm /tmp/temp_pubkey.pub; echo 'SSH key added'"
Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Cheie publică copiată pe Proxmox!" -ForegroundColor Green
} else {
Write-Host "✗ Eroare la adăugarea cheii în authorized_keys" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "→ Testez conexiunea SSH fără parolă..." -ForegroundColor Yellow
# Testează conexiunea (cu cheia din profilul SYSTEM)
$testResult = & ssh -o StrictHostKeyChecking=no -i $PrivateKeyPath "${ProxmoxUser}@${ProxmoxHost}" "echo 'SSH connection OK'" 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Conexiune SSH funcționează fără parolă!" -ForegroundColor Green
} else {
Write-Host "✗ Conexiunea SSH nu funcționează direct din acest cont" -ForegroundColor Yellow
Write-Host " Dar cheia a fost adăugată - scheduled tasks (SYSTEM) ar trebui să funcționeze" -ForegroundColor Yellow
}
Write-Host ""
Write-Host "=========================================" -ForegroundColor Green
Write-Host "✓ Setup complet!" -ForegroundColor Green
Write-Host "=========================================" -ForegroundColor Green
Write-Host ""
Write-Host "Cheia din profilul SYSTEM: $PrivateKeyPath" -ForegroundColor Cyan
Write-Host "Scheduled tasks vor folosi această cheie automat." -ForegroundColor Yellow
Write-Host ""

View File

@@ -0,0 +1,89 @@
# Setup SSH Keys for PRIMARY → Proxmox DR Transfer
# Rulează acest script MANUAL pe PRIMARY ca Administrator
#
# Acest script:
# 1. Generează chei SSH în profilul curent ($env:USERPROFILE\.ssh)
# 2. Copiază cheia publică pe Proxmox host (10.0.20.202)
# 3. Testează conexiunea SSH
param(
[string]$ProxmoxHost = "10.0.20.202",
[string]$ProxmoxUser = "root"
)
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host "SSH Key Setup pentru PRIMARY → Proxmox DR" -ForegroundColor Cyan
Write-Host "=========================================" -ForegroundColor Cyan
Write-Host ""
$SSHDir = "$env:USERPROFILE\.ssh"
$PrivateKeyPath = "$SSHDir\id_rsa"
$PublicKeyPath = "$SSHDir\id_rsa.pub"
# Verifică dacă cheia există deja
if (Test-Path $PrivateKeyPath) {
Write-Host "✓ SSH key deja există: $PrivateKeyPath" -ForegroundColor Green
Write-Host " Voi folosi cheia existentă." -ForegroundColor Yellow
} else {
Write-Host "→ Generez SSH key pair..." -ForegroundColor Yellow
# Creează directorul .ssh dacă nu există
if (-not (Test-Path $SSHDir)) {
New-Item -ItemType Directory -Path $SSHDir -Force | Out-Null
}
# Generează cheia SSH (fără parolă pentru automatizare)
& ssh-keygen.exe -t rsa -b 4096 -f $PrivateKeyPath -N '""' -C "PRIMARY-RMAN-to-Proxmox"
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Cheie SSH generată cu succes!" -ForegroundColor Green
} else {
Write-Host "✗ Eroare la generarea cheii SSH" -ForegroundColor Red
exit 1
}
}
Write-Host ""
Write-Host "→ Citesc cheia publică..." -ForegroundColor Yellow
$PublicKey = Get-Content $PublicKeyPath -Raw
Write-Host "→ Copiez cheia publică pe Proxmox ($ProxmoxHost)..." -ForegroundColor Yellow
Write-Host " IMPORTANT: Vei fi întrebat de parola root pentru Proxmox!" -ForegroundColor Cyan
Write-Host ""
# Copiază cheia publică pe Proxmox
$command = "mkdir -p /root/.ssh && chmod 700 /root/.ssh && echo '$PublicKey' >> /root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys && echo 'SSH key adăugat cu succes!'"
& ssh "${ProxmoxUser}@${ProxmoxHost}" $command
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Cheie publică copiată pe Proxmox!" -ForegroundColor Green
} else {
Write-Host "✗ Eroare la copierea cheii pe Proxmox" -ForegroundColor Red
Write-Host " Verifică dacă ai acces SSH la Proxmox cu parolă" -ForegroundColor Yellow
exit 1
}
Write-Host ""
Write-Host "→ Testez conexiunea SSH fără parolă..." -ForegroundColor Yellow
# Testează conexiunea
& ssh -o StrictHostKeyChecking=no -i $PrivateKeyPath "${ProxmoxUser}@${ProxmoxHost}" "echo 'SSH connection OK'"
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ Conexiune SSH funcționează fără parolă!" -ForegroundColor Green
} else {
Write-Host "✗ Conexiunea SSH nu funcționează" -ForegroundColor Red
exit 1
}
Write-Host ""
Write-Host "=========================================" -ForegroundColor Green
Write-Host "✓ Setup complet!" -ForegroundColor Green
Write-Host "=========================================" -ForegroundColor Green
Write-Host ""
Write-Host "Cheia privată: $PrivateKeyPath" -ForegroundColor Cyan
Write-Host "Cheia publică: $PublicKeyPath" -ForegroundColor Cyan
Write-Host ""
Write-Host "Scripturile de transfer vor folosi această cheie automat." -ForegroundColor Yellow
Write-Host ""

View File

@@ -0,0 +1,130 @@
# 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
}
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
}
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
}

201
input/transfer_to_dr.ps1 Normal file
View File

@@ -0,0 +1,201 @@
# 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.202",
[int]$DRPort = 22,
[string]$DRUser = "root",
[string]$DRPath = "/mnt/pve/oracle-backups/ROA/autobackup",
[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) - Linux bash command
$checkCmd = "test -f '$DestPath/$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"
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 - Linux find command
$cleanupCmd = "find '$DRPath' -type f -mtime +$RetentionDays -delete 2>/dev/null || true"
$result = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" $cleanupCmd 2>&1
Write-Log "Cleanup completed on DR (removed files older than $RetentionDays days)"
} 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 - Linux mkdir command
Write-Log "Ensuring DR directory exists..."
$null = & ssh -n -p $DRPort -i $SSHKeyPath "${DRUser}@${DRHost}" "mkdir -p '$DRPath'" 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
}