Caricamento in corso

[Veeam] Veeam 13.1: risolvere i warning PostgreSQL dopo l’upgrade

Se dopo l’aggiornamento a Veeam Backup & Replication 13.1 ti sei ritrovato job che fino al giorno prima erano verdi e adesso chiudono con un warning PostgreSQL Veeam 13.1 che prima non c’era, non hai rotto nulla: è un cambio di comportamento introdotto proprio in questa release.

Il messaggio tipico che arriva via mail è questo:

Failed to explore PostgreSQL instance NOMEVM:5432 : No response from PostgreSQL
server on port 5432. Failed to invoke rpc command
Processing finished with warnings at ...

Il backup è completo, i dati ci sono tutti, ma il job non è più verde. E su un ambiente monitorato, un warning ricorrente è rumore che a lungo andare fa perdere di vista i problemi veri.

In questa guida vediamo perché succede, come individuare l’istanza responsabile e come applicare il workaround ufficiale confermato dal supporto Veeam.

Cosa è cambiato nella 13.1

Fino alla versione 13.0, l’Application-Aware Processing per PostgreSQL esisteva solo per i guest Linux. Con la 13.1 Veeam ha esteso il supporto anche alle macchine Windows.

Sulla carta è un’ottima notizia: significa poter fare backup transazionalmente consistenti di PostgreSQL su Windows e usare il Veeam Explorer for PostgreSQL per il ripristino granulare.

Nella pratica, però, l’agente di guest processing (pgsqlagent) ora scansiona il file system alla ricerca dei file di configurazione PostgreSQL — postgresql.conf, pg_hba.conf, pg_ident.conf — e quando ne trova uno tenta di connettersi all’istanza per interrogarla.

Il problema nasce con le istanze embedded: quelle che non hai installato tu, ma che arrivano insieme a un applicativo di terze parti. Sono ovunque, molto più di quanto si immagini.

Queste istanze sono gestite dal vendor: le credenziali sono cablate nella configurazione dell’applicativo, non c’è un modo supportato per amministrarle dall’esterno, e quasi sempre ascoltano solo su localhost.

Veeam le trova, prova a connettersi con le credenziali di guest processing, non ci riesce, e segnala un warning.

Nota sull’errore. Esistono due varianti del messaggio. No response from PostgreSQL server on port X significa che il TCP non si è nemmeno aperto: tipicamente l’istanza ascolta solo su 127.0.0.1 mentre Veeam tenta la connessione risolvendo l’hostname della VM sull’IP di rete. Password authentication failed for user significa invece che la connessione è avvenuta ma le credenziali sono sbagliate. La causa di fondo, e la soluzione, sono le stesse.

Perché non basta la GUI

La domanda naturale è: posso disattivare il solo processing di PostgreSQL e lasciare attivi Microsoft SQL e Oracle?

La risposta di Veeam è no. Dalla console non esiste un interruttore per singola applicazione: l’Application-Aware Processing si abilita o si disabilita in blocco. Disabilitarlo del tutto significherebbe perdere anche il troncamento dei log e la consistenza applicativa su SQL Server, cosa che su una VM produttiva non è accettabile.

La strada corretta passa da un file di configurazione dentro il guest.

Individuare le istanze PostgreSQL sulla VM

Prima di scrivere qualsiasi esclusione bisogna sapere dove si trovano davvero i file di configurazione. Il percorso varia da applicativo ad applicativo e quasi mai coincide con l’installazione standard di PostgreSQL.

Apri PowerShell come amministratore sulla macchina interessata (oppure usa Enter-PSSession -ComputerName NOMEVM) ed esegui:

# 1) Istanze attive con la relativa data directory e porta
Get-CimInstance Win32_Process -Filter "Name='postgres.exe'" |
  Select-Object -ExpandProperty CommandLine | Sort-Object -Unique

# 2) Percorsi degli eseguibili in esecuzione
Get-Process postgres -ErrorAction SilentlyContinue |
  Select-Object -ExpandProperty Path -Unique

# 3) Ricerca dei file di configurazione su tutti i dischi fissi
Get-Volume | Where-Object { $_.DriveType -eq 'Fixed' -and $_.DriveLetter } | ForEach-Object {
  $d = "$($_.DriveLetter):\"
  Write-Host "--- $d ---" -ForegroundColor Cyan
  robocopy $d NULL postgresql.conf pg_hba.conf /S /L /NJH /NJS /NDL /NC /NS /NP /XJ /R:0 /W:0 |
    Where-Object { $_ -match '\S' }
}

Il primo comando è il più veloce e spesso risolve da solo: la riga di comando del processo postmaster contiene il parametro -D con il percorso esatto della data directory, e talvolta anche -p con la porta.

Il terzo comando usa robocopy in modalità sola-lista invece di Get-ChildItem: su volumi con centinaia di migliaia di file è drasticamente più rapido. I parametri /L (nessuna copia), /NDL (non elencare le directory attraversate) e /XJ (ignora i junction point) servono a ottenere un output pulito senza effetti collaterali.

Un esempio di output reale su un server ManageEngine:

E:\ManageEngine\ADAudit Plus\pgsql\data\postgresql.conf
E:\ManageEngine\ADAudit Plus\pgsql\data\pg_hba.conf
E:\ManageEngine\EventLog Analyzer\pgsql\data\postgresql.conf
E:\ManageEngine\EventLog Analyzer\pgsql\data\pg_hba.conf

Due istanze distinte sulla stessa VM, entrambe embedded, entrambe su porte non standard. Il job segnalava infatti due warning identici, uno per istanza: un buon indizio per capire quante istanze sono coinvolte prima ancora di andare a cercarle.

Il workaround: VeeamPostgreSQLAgent.xml

La soluzione: si crea nel guest un file XML che indica all’agente quali directory non scansionare. Se l’agente non trova la configurazione, non tenta la connessione, e il warning sparisce.

Il file si chiama VeeamPostgreSQLAgent.xml e la sua posizione dipende dal sistema operativo:

SistemaPercorso
WindowsC:\ProgramData\Veeam\Backup\PostgreSqlConfig\
Linux/etc/veeam/

Il contenuto è una singola riga:

<config ExcludeConfigDirs="E:\ManageEngine\" />

Due dettagli che fanno la differenza:

  • il match avviene per prefisso ricorsivo, quindi indicare la directory radice dell’applicativo copre tutte le istanze che stanno sotto, incluse quelle che verranno installate in futuro;
  • il backslash finale va sempre messo.

Per escludere più percorsi non correlati si usa lo stesso attributo con i valori separati da virgola:

<config ExcludeConfigDirs="E:\ManageEngine\,D:\ArcGIS\PostgreSQL\" />

Lo stesso file supporta anche l’attributo AddConfigDirs, che fa l’opposto: aggiunge alla scansione directory in posizioni non convenzionali. Utile quando hai un’istanza tua, che vuoi davvero proteggere in modo applicativo, installata fuori dai percorsi standard.

Script pronto all’uso

Questo script crea la cartella, salva una copia di backup di un eventuale file preesistente, scrive l’XML e riavvia i servizi Veeam nel guest:

$dir  = 'C:\ProgramData\Veeam\Backup\PostgreSqlConfig'
$file = Join-Path $dir 'VeeamPostgreSQLAgent.xml'

New-Item -Path $dir -ItemType Directory -Force | Out-Null
if (Test-Path $file) {
    Copy-Item $file "$file.$(Get-Date -Format yyyyMMdd-HHmmss).bak" -Force
}

# <-- ADATTA QUESTO PERCORSO al risultato della ricerca, backslash finale incluso
$xml = '<config ExcludeConfigDirs="E:\ManageEngine\" />'

[System.IO.File]::WriteAllText($file, $xml, (New-Object System.Text.UTF8Encoding($false)))

Get-Content $file
Get-Service Veeam* | Restart-Service -Force
Get-Service Veeam* | Select-Object Name, Status

Encoding. Nello script uso [System.IO.File]::WriteAllText con UTF8Encoding($false) invece del più comodo Set-Content -Encoding UTF8. Il motivo è che in Windows PowerShell 5.1 quest’ultimo scrive il BOM in testa al file, e un parser XML può inciampare su quei tre byte. Con PowerShell 7 il comportamento predefinito è diverso, ma la forma esplicita funziona su entrambi.

La versione Linux è identica nella sostanza, cambia solo il percorso:

sudo mkdir -p /etc/veeam
echo '<config ExcludeConfigDirs="/opt/applicativo/pgsql/data/" />' | \
  sudo tee /etc/veeam/VeeamPostgreSQLAgent.xml

Verifica

Dopo aver scritto il file, rilancia il job sulla VM interessata e osserva la fase di guest processing nella sessione: le righe Failed to explore PostgreSQL instance non devono più comparire e il job deve chiudere in Success.

Se il warning persiste, nella quasi totalità dei casi l’agente non ha riletto la configurazione. Il riavvio dei servizi Veeam nel guest risolve; in alternativa un riavvio della VM è definitivo.

Per controllare a colpo d’occhio lo stato su più macchine:

$vms = @('nomevm1','nomevm2')
foreach ($vm in $vms) {
  $p = "\\$vm\c$\ProgramData\Veeam\Backup\PostgreSqlConfig\VeeamPostgreSQLAgent.xml"
  [pscustomobject]@{
    VM      = $vm
    XmlOk   = Test-Path $p
    Content = if (Test-Path $p) { (Get-Content $p -Raw).Trim() } else { '' }
  }
}

Cosa si perde e cosa resta protetto

È la domanda più importante, perché escludere qualcosa dal backup suona sempre come un compromesso sulla sicurezza del dato. Qui il compromesso è molto contenuto.

Cosa si perde: il Veeam Explorer for PostgreSQL sull’istanza esclusa. Non potrai fare ripristino granulare di singoli database o item da quell’istanza.

Cosa resta: i file del database continuano a essere protetti tramite VSS, esattamente come funzionava fino alla 13.0 e come ha sempre funzionato prima che l’AAP per PostgreSQL su Windows esistesse. Un ripristino completo della VM, o un Instant Recovery, restituisce un applicativo funzionante.

In altre parole: torni al comportamento che avevi ieri, quello con cui l’ambiente ha funzionato per anni.

Il ripristino davvero supportato. Per applicativi come quelli ManageEngine, il ripristino consigliato dal vendor non passa comunque dal file-level della data directory, ma dagli strumenti nativi di backup del prodotto (per esempio backUpData.bat, schedulabile). Se su quelle VM non hai già un backup applicativo nativo attivo, questa è l’occasione buona per metterlo in piedi: è la vera rete di sicurezza per quei dati, il backup Veeam è il livello sottostante.

L’alternativa: configurare l’AAP correttamente

L’esclusione è la scelta giusta per le istanze embedded gestite dal vendor. Ma se sulla VM gira una PostgreSQL tua, di produzione, ha molto più senso configurare l’Application-Aware Processing come si deve e sfruttare la nuova funzionalità invece di aggirarla.

In quel caso il percorso è: proprietà del job → Guest ProcessingApplications → seleziona la VM → Edit → scheda PostgreSQL, dove indichi un account con privilegi di superuser.

Perché funzioni serve però che l’istanza sia effettivamente raggiungibile dall’agente. I punti da verificare sono i classici:

  • listen_addresses in postgresql.conf deve includere l’indirizzo su cui Veeam si connette, non solo localhost;
  • pg_hba.conf deve avere una entry host che autorizzi la connessione dall’IP della macchina;
  • il firewall locale non deve bloccare la porta dell’istanza.

Riferimenti