Arhitecturi de High Availability în PostgreSQL: Replicare Fizică, Patroni și PgBouncer în PostgreSQL

Ghid complet pentru disponibilitate înaltă (HA) în PostgreSQL: streaming replication sincron vs asincron, failover automat fără split-brain cu Patroni și etcd și optimizarea conexiunilor cu PgBouncer.

Sintaxă SQL
pg_basebackup; Patroni + etcd / Consul; PgBouncer pool_mode = transaction

Pentru sistemele care necesită disponibilitate continuă (SLA 99.99%) și protecție împotriva căderilor hardware, o singură instanță PostgreSQL reprezintă un punct unic de eșec (Single Point of Failure – SPOF). O arhitectură robustă de producție necesită un cluster format dintr-un nod primar (Primary/Leader), replici în standby (Secondaries), un mecanism automat de consens pentru failover și un nivel de multiplexare a conexiunilor.

Cum funcționează Replicarea Fizică prin Streaming (Streaming Replication)
-- Pe serverul Primary:
-- Creăm un utilizator dedicat cu dreptul REPLICATION:
CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD 'ParolaSiguraReplica2026!';

-- Creăm un Replication Slot fizic pentru a garanta că Primary NU șterge fișierele WAL
-- înainte ca replica să le fi descărcat:
SELECT pg_create_physical_replication_slot('replica_node_1');

-- Pe serverul Replica (inițializare prin clonare la cald):
-- pg_basebackup -h 10.0.1.10 -U repl_user -D /var/lib/postgresql/data -Fp -Xs -R --slot=replica_node_1

Replicare Asincronă vs. Replicare Sincronă

Mod Replicare Comportament la COMMIT Performanță Garanție Pierdere Date
Asincronă
(Default)
Primary returnează succes clientului imediat ce WAL-ul a fost scris local, fără a aștepta confirmare de la replici. Maximă (fără latență adăugată pe tranzacții). Risc de pierdere a tranzacțiilor aflate în tranzit de rețea dacă nodul Primary suferă un crash brusc.
Sincronă
(synchronous_commit = on)
Primary așteaptă confirmarea că cel puțin un nod Standby a scris segmentul WAL pe disc înainte de a finaliza COMMIT. Depinde de latența de rețea (RTT) dintre servere. Zero Data Loss (RPO = 0) garantat matematic.

Standardul de Aur pentru Failover Automat: Patroni + DCS (etcd)

Cea mai mare provocare în clustering-ul de baze de date este prevenirea fenomenului de Split-Brain (situația periculoasă în care două noduri cred că sunt ambele lider și acceptă scrieri concurente, corupând iremediabil consistența datelor).

Patroni este un orchestrator open-source de High Availability pentru PostgreSQL care folosește un sistem de stocare distribuită a consensului (DCS precum etcd sau Consul pe algoritmul Raft):

  1. Fiecare nod PostgreSQL este supravegheat continuu de un agent daemon Patroni local.
  2. Nodul Leader obține o cheie de blocaj temporară (Leader Lock) în clusterul etcd și o reînnoiește prin semnale periodice de tip heartbeat.
  3. Dacă nodul Leader nu mai răspunde în intervalul configurat (ex: 10 secunde), cheia expiră.
  4. Nodurile Standby declanșează instantaneu o rundă democratică de alegeri. Replica cea mai sincronizată (cu cel mai mare LSN – Log Sequence Number) este promovată automat la rangul de nou Leader.
  5. Vechiul nod căzut este reconfigurat automat ca Standby la repornire, eliminând orice posibilitate de split-brain!

PgBouncer: Connection Pooling Obligatoriu în Producție

Deoarece PostgreSQL creează un proces separat din sistemul de operare pentru fiecare conexiune conectată, scalarea la peste 300-500 de conexiuni directe duce la colapsul performanței prin consum masiv de memorie RAM și context-switching excesiv al procesorului.

Configurarea PgBouncer în modul ‘transaction’
# /etc/pgbouncer/pgbouncer.ini
[databases]
baza_productie = host=127.0.0.1 port=5432 dbname=baza_productie

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt

# Modul recomandat pentru microservicii web stateless (Node.js, PHP, Python, Go):
pool_mode = transaction

# Permite deservirea a 10.000 de conexiuni client simultane:
max_client_conn = 10000

# Folosind doar 60 de conexiuni reale deschise pe serverul PostgreSQL fizic!
default_pool_size = 60

Monitorizarea Replicării în Timp Real

Pe serverul Primary, inspectați starea tuturor replicilor conectate prin interogarea de sistem:

SELECT 
    application_name,
    client_addr,
    state,
    sync_state,
    -- Decalajul de replicare măsurat în octeți (Lag):
    pg_wal_lsn_diff(pg_current_wal_lsn(), write_lsn) AS write_lag_bytes,
    pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_lag_bytes
FROM pg_stat_replication;