# Lexware PostgreSQL Dump -> Push nach Linux # Laeuft als Windows Scheduled Task alle 2 Minuten $pgDump = "C:\Program Files\Lexware\PostgreSql\17\Bin\pg_dump.exe" $pgCtl = "C:\Program Files\Lexware\PostgreSql\17\Bin\pg_ctl.exe" $dataDir = "C:\ProgramData\Lexware\LexwarePG\Data\current" $hbaFile = "$dataDir\pg_hba.conf" $dumpDir = "C:\lexware-db-connect\dumps" $linuxHost = "root@192.168.115.113" $linuxDir = "/opt/lexware-dumps" $sshKey = "C:\lexware-db-connect\ssh\id_rsa" $logFile = "C:\Users\Administrator\Desktop\LexWare-DB-Mirror.log" $lockFile = "C:\lexware-db-connect\push-dump.lock" $maxLines = 500 # Datenbanken die gedumpt werden sollen $databases = @("f1", "f2", "lexkonto", "lexkk", "rk", "lxoffice", "lx", "lxcatalog") $utf8NoBom = [System.Text.UTF8Encoding]::new($false) function Write-Log { param([string]$Message, [string]$Level = "INFO") $ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $entry = "[$ts] [$Level] $Message`n" [System.IO.File]::AppendAllText($logFile, $entry, $utf8NoBom) # Log auf 500 Zeilen begrenzen $content = [System.IO.File]::ReadAllLines($logFile) if ($content.Count -gt $maxLines) { $trimmed = $content | Select-Object -Last $maxLines [System.IO.File]::WriteAllLines($logFile, $trimmed, $utf8NoBom) } } # --- 0. Doppelausfuehrung verhindern --- if (Test-Path $lockFile) { $lockAge = (Get-Date) - (Get-Item $lockFile).LastWriteTime if ($lockAge.TotalMinutes -lt 10) { exit 0 } Remove-Item $lockFile -Force } New-Item -ItemType File -Path $lockFile -Force | Out-Null try { # --- 1. Dumpverzeichnis anlegen --- New-Item -ItemType Directory -Force -Path $dumpDir | Out-Null $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm" $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() Write-Log "===== Sync-Lauf gestartet ($timestamp) =====" "INFO" # --- 2. Trust-Regel fuer lxdump hinzufuegen (wird am Ende wieder entfernt) --- $trustRule = "host all lxdump 127.0.0.1/32 trust" $lines = Get-Content $hbaFile if ($lines -notmatch "lxdump") { $newLines = [System.Collections.Generic.List[string]]::new() $inserted = $false foreach ($line in $lines) { if (-not $inserted -and $line -match "127\.0\.0\.1/32") { $newLines.Add($trustRule) $inserted = $true } $newLines.Add($line) } [System.IO.File]::WriteAllLines($hbaFile, $newLines, [System.Text.Encoding]::ASCII) & $pgCtl reload -D $dataDir 2>&1 | Out-Null Start-Sleep -Seconds 2 } # --- 3. lxdump User anlegen falls nicht vorhanden --- $env:PGSSLMODE = "disable" $env:PGPASSWORD = "" $env:PGCLIENTENCODING = "LATIN1" $sql = @' DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'lxdump') THEN CREATE USER lxdump WITH SUPERUSER LOGIN; END IF; END $$; '@ & "C:\Program Files\Lexware\PostgreSql\17\Bin\psql.exe" -h 127.0.0.1 -p 15432 -U altertillattbruker -d postgres -c $sql 2>&1 | Out-Null # --- 4. Dumps erstellen und nach Linux pushen --- $errors = @() $okCount = 0 foreach ($db in $databases) { $dumpFile = "$dumpDir\${db}_${timestamp}.dump" & $pgDump -h 127.0.0.1 -p 15432 -U lxdump -d $db -Fc -f $dumpFile 2>&1 | Out-Null if ($LASTEXITCODE -ne 0) { Write-Log " $db -> DUMP FEHLGESCHLAGEN" "ERROR" $errors += $db continue } $dumpSize = if (Test-Path $dumpFile) { "{0:N1} MB" -f ((Get-Item $dumpFile).Length / 1MB) } else { "?" } & scp -i $sshKey -o StrictHostKeyChecking=no $dumpFile "${linuxHost}:${linuxDir}/${db}_${timestamp}.dump" 2>&1 | Out-Null if ($LASTEXITCODE -eq 0) { try { Invoke-WebRequest -Uri "http://192.168.115.113:9055/restore?db=$db" -Method POST -UseBasicParsing -TimeoutSec 5 | Out-Null } catch {} Write-Log " $db -> OK ($dumpSize)" "INFO" $okCount++ } else { Write-Log " $db -> SCP FEHLGESCHLAGEN ($dumpSize)" "ERROR" $errors += $db } Remove-Item $dumpFile -Force } # --- 5. Trust-Regel wieder entfernen --- $lines = Get-Content $hbaFile | Where-Object { $_ -notmatch "lxdump" } [System.IO.File]::WriteAllLines($hbaFile, $lines, [System.Text.Encoding]::ASCII) & $pgCtl reload -D $dataDir 2>&1 | Out-Null # --- 6. Alte Dumps auf Linux aufraemen (nur letzte 5 pro DB behalten) --- & ssh -i $sshKey -o StrictHostKeyChecking=no root@192.168.115.113 @" for db in f1 f2 lexkonto lexkk rk lxoffice lx lxcatalog; do ls -t /opt/lexware-dumps/\${db}_*.dump 2>/dev/null | tail -n +6 | xargs -r rm -f done "@ 2>&1 | Out-Null # --- 7. Zusammenfassung loggen --- $stopwatch.Stop() $elapsed = "{0:mm\:ss}" -f $stopwatch.Elapsed if ($errors.Count -gt 0) { Write-Log " Ergebnis: $okCount/$($databases.Count) OK | Fehler: $($errors -join ', ') | Dauer: $elapsed" "WARN" Write-Log "===== Sync-Lauf beendet =====" "INFO" } else { Write-Log " Ergebnis: $okCount/$($databases.Count) OK | Alle synchronisiert | Dauer: $elapsed" "INFO" Write-Log "===== Sync-Lauf beendet =====" "INFO" } } finally { # Trust-Regel sicher entfernen (auch bei Absturz) $lines = Get-Content $hbaFile -ErrorAction SilentlyContinue | Where-Object { $_ -notmatch "lxdump" } if ($lines) { [System.IO.File]::WriteAllLines($hbaFile, $lines, [System.Text.Encoding]::ASCII) & $pgCtl reload -D $dataDir 2>&1 | Out-Null } Remove-Item $lockFile -Force -ErrorAction SilentlyContinue }