Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

PostgreSQL streaming replication — konfiguracja HA

Opublikowano: 9 kwietnia 2026 · Kategoria: Bazy danych / VPS

Jedna instancja PostgreSQL to single point of failure — gdy serwer padnie, aplikacja przestaje działać. Streaming replication pozwala utrzymać hot standby (ciepłą rezerwę): replika na bieżąco otrzymuje zmiany z primary i w razie awarii może przejąć ruch w ciągu sekund. Oto jak skonfigurować replikację od podstaw.

Architektura streaming replication

PostgreSQL streaming replication działa przez protokół WAL (Write Ahead Log): primary zapisuje każdą zmianę do WAL przed jej zastosowaniem na dysku. Replika podłącza się do primary przez specjalne połączenie replikacji i strumieniuje (streaming) kolejne rekordy WAL:

  • Primary — przyjmuje zapisy i odczyty. Wysyła WAL do replik w czasie rzeczywistym.
  • Standby / Replica — tylko odczyty (read-only). Stosuje WAL od primary. Może obsługiwać zapytania raportowe, backupy, analizy.
  • Synchronous standby — opcjonalnie: primary czeka na potwierdzenie od repliki przed odpowiedzią klientowi. Zero utraty danych, ale większe opóźnienia zapisu.
  • Asynchronous standby — domyślny tryb. Primary nie czeka na replikę — minimalne opóźnienia, ryzyko utraty ostatnich transakcji przy failoverze.

Krok 1 — Konfiguracja primary

Edytuj postgresql.conf na serwerze primary (zazwyczaj /etc/postgresql/16/main/postgresql.conf lub /var/lib/postgresql/data/postgresql.conf):

# postgresql.conf na PRIMARY

# Wymagane: włącz WAL dla replikacji
wal_level = replica            # Minimalne: replica. Dla logical: logical

# Maksymalna liczba jednoczesnych połączeń replikacji
max_wal_senders = 10           # 1 na każdą replikę + zapas

# Ile WAL zachować na primary (dla repliki która jest chwilowo offline)
wal_keep_size = 1GB            # PostgreSQL 13+; starsze: wal_keep_segments = 64

# Opcjonalnie: synchroniczna replikacja (zero utraty danych)
# synchronous_standby_names = 'replica1'
# synchronous_commit = on

# Archiwizacja WAL (dla Point-in-Time Recovery)
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f'

Następnie utwórz użytkownika replikacji w pg_hba.conf:

# Utwórz użytkownika replikacji
psql -U postgres -c "CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'haslo_replikacji';"

# pg_hba.conf — dodaj wpis dla repliki (IP: 10.0.0.11)
# Plik: /etc/postgresql/16/main/pg_hba.conf
# TYPE  DATABASE    USER        ADDRESS         METHOD
host    replication replicator  10.0.0.11/32    scram-sha-256

# Przeładuj konfigurację
sudo systemctl reload postgresql

Krok 2 — pg_basebackup na replice

Na serwerze repliki wykonaj bazowe kopiowanie danych z primary przez pg_basebackup. To jednorazowa operacja inicjalizacyjna:

# Na serwerze REPLIKI — zatrzymaj PostgreSQL
sudo systemctl stop postgresql

# Usuń istniejące dane (UWAGA: niszczy dane lokalne)
sudo rm -rf /var/lib/postgresql/16/main/*

# Skopiuj dane z primary (IP: 10.0.0.10)
sudo -u postgres pg_basebackup \
  -h 10.0.0.10 \
  -U replicator \
  -D /var/lib/postgresql/16/main \
  -P \
  --wal-method=stream \
  --checkpoint=fast

# -P = pokaż postęp
# --wal-method=stream = strumieniuj WAL podczas backupu
# --checkpoint=fast = szybki checkpoint na primary przed startem

Krok 3 — konfiguracja standby

Po pg_basebackup skonfiguruj replikę. W PostgreSQL 12+ wystarczą dwa pliki:

# 1. Utwórz plik standby.signal (pusty plik — sygnalizuje tryb standby)
sudo -u postgres touch /var/lib/postgresql/16/main/standby.signal

# 2. Dodaj primary_conninfo do postgresql.auto.conf
sudo -u postgres tee -a /var/lib/postgresql/16/main/postgresql.auto.conf <<EOF
primary_conninfo = 'host=10.0.0.10 port=5432 user=replicator password=haslo_replikacji application_name=replica1'
primary_slot_name = 'replica1_slot'
EOF

# 3. Opcjonalnie: utwórz replication slot na primary (zabezpiecza WAL)
# psql -U postgres -h 10.0.0.10 -c "SELECT pg_create_physical_replication_slot('replica1_slot');"

# 4. Uruchom PostgreSQL na replice
sudo systemctl start postgresql

Weryfikacja replikacji

# Na PRIMARY — sprawdź podłączone repliki
psql -U postgres -c "SELECT client_addr, state, sent_lsn, replay_lsn,
  (sent_lsn - replay_lsn) AS lag_bytes
  FROM pg_stat_replication;"

# Wynik: state=streaming, lag_bytes bliskie 0 = OK

# Na REPLICE — sprawdź czy jest w trybie recovery
psql -U postgres -c "SELECT pg_is_in_recovery();"
# Wynik: t (true) = replika

# Opóźnienie czasowe na replice
psql -U postgres -c "SELECT now() - pg_last_xact_replay_timestamp() AS delay;"

Parametry konfiguracyjne — tabela

Parametr Wartość Opis
wal_level replica Minimalny poziom WAL dla replikacji fizycznej
max_wal_senders 10 Maks. liczba jednoczesnych połączeń replikacji
wal_keep_size 1GB Ile WAL zachować gdy replika jest offline (PG13+)
hot_standby on (domyślnie) Zezwala na odczyty na replice podczas recovery
recovery_min_apply_delay 0 Opóźnienie aplikowania WAL — zabezpieczenie przed DROP TABLE

Patroni — automatyczny failover

Ręczna replikacja streaming nie ma automatycznego failoveru — gdy primary padnie, administrator musi ręcznie promować replikę. Patroni to open-source HA manager (Zalando) który automatyzuje ten proces:

  • Używa etcd / Consul / ZooKeeper jako distributed consensus store — dokładnie jeden węzeł jest leaderem (primary) w każdym momencie.
  • Gdy primary nie odpowiada, Patroni przeprowadza wybory i promuje najlepszą replikę, rekonfiguruje pozostałe jako repliki nowego primary.
  • Udostępnia REST API (/health, /leader, /replicas) — HAProxy lub Nginx mogą używać go do health check i routingu ruchu.
  • Obsługuje planned switchover bez utraty danych: promuje replikę gdy primary jest zdrowy (np. na czas maintenence).

pgBouncer — connection pooling

PostgreSQL jest kosztowny przy tworzeniu połączeń — każde połączenie to osobny proces OS. pgBouncer rozwiązuje ten problem jako lekki connection pooler:

# pgbouncer.ini — podstawowa konfiguracja
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
listen_addr = 127.0.0.1
listen_port = 5432        # pgBouncer słucha na 5432, PostgreSQL przeniesiony na 5433
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction   # transaction/session/statement
max_client_conn = 1000    # Maks. połączeń od aplikacji
default_pool_size = 20    # Maks. połączeń do PostgreSQL

Tryb transaction to najefektywniejszy tryb poolingu: jedno połączenie do PostgreSQL obsługuje wiele klientów aplikacji, bo każda transakcja może trafić do innego połączenia. Ograniczenie: nie obsługuje SET, LISTEN, prepared statements (bez modyfikacji aplikacji).

Najczęstsze pytania

Czym różni się streaming replication od logical replication w PostgreSQL? +
Streaming replication (fizyczna) replikuje zmiany na poziomie bloków danych (WAL — Write Ahead Log) — replika jest dokładną kopią primary, na tym samym poziomie wersji PostgreSQL. Logical replication replikuje zmiany na poziomie wierszy i tabel (protokół logiczny), umożliwiając replikację między różnymi wersjami PostgreSQL, różnymi serwerami, a nawet selektywną replikację wybranych tabel. Streaming = HA i disaster recovery. Logical = migracje, upgrade bez downtime, CDC (Change Data Capture).
Jak sprawdzić opóźnienie replikacji (lag) w PostgreSQL? +
Na primary: SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, (sent_lsn - replay_lsn) AS replication_lag FROM pg_stat_replication; — pole replication_lag pokazuje lag w bajtach WAL. Na replice: SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay; — opóźnienie czasowe od ostatnio zastosowanej transakcji. Normalny lag przy małym obciążeniu to 0-10ms. Lag powyżej 1-5 sekund wymaga analizy.
Co to jest Patroni i kiedy go używać? +
Patroni to open-source HA manager dla PostgreSQL napisany przez Zalando. Automatyzuje failover (promowanie repliki na primary gdy primary padnie), zarządza konfiguracją przez etcd/Consul/ZooKeeper jako distributed consensus store, udostępnia REST API do zarządzania klastrem. Patroni używaj gdy: potrzebujesz automatycznego failoveru bez ręcznej interwencji, masz więcej niż 2 serwery PostgreSQL, lub budujesz środowisko produkcyjne klasy enterprise. Dla małych projektów (2 serwery) ręczny failover lub repmgr są prostszą opcją.
Co to jest pgBouncer i dlaczego jest potrzebny przy replikacji? +
pgBouncer to connection pooler dla PostgreSQL — zbiera połączenia od aplikacji i utrzymuje mały pool realnych połączeń do bazy. Bez poolera każdy request PHP/Python/Node.js otwiera nowe połączenie PostgreSQL, co przy dużym ruchu prowadzi do wyczerpania max_connections (domyślnie 100). pgBouncer stawia się przed primary i repliką — aplikacja łączy się do pgBouncer, nie bezpośrednio do PostgreSQL. Tryb transaction pooling: jedno połączenie może obsłużyć setki klientów przy transakcjach o krótkim czasie trwania.

Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.