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

PostgreSQL Streaming Replication — primary i standby

Opublikowano: 10 kwietnia 2026 · Kategoria: VPS i serwery

Backup jest niezbędny, ale nie wystarczy. Gdy serwer PostgreSQL ulega awarii, przywrócenie bazy z pg_dump może zająć godziny. Streaming Replication utrzymuje w trybie gotowości jeden lub kilka serwerów standby, które mają aktualną kopię bazy i mogą w ciągu sekund przejąć rolę primary. Dodatkowo standby może obsługiwać zapytania read-only, odciążając primary. Ten artykuł pokazuje jak skonfigurować replikację fizyczną PostgreSQL 15/16 na dwóch serwerach, uruchomić hot standby i przeprowadzić kontrolowany failover.

Konfiguracja primary — postgresql.conf i pg_hba.conf

# Na PRIMARY: /etc/postgresql/16/main/postgresql.conf

# Wlacz archiwizacje WAL
wal_level = replica           # replica lub logical
max_wal_senders = 5           # liczba rownoleglych polaczen replikacji
wal_keep_size = 1GB           # trzymaj WAL do synchronizacji (PostgreSQL 13+)
# Lub uzywaj replication slots zamiast wal_keep_size

# Hot standby — pozwala replike obsługiwac SELECTy
hot_standby = on

# Dla synchronicznej replikacji (opcjonalnie — wolniejsza, ale brak utraty danych)
# synchronous_standby_names = 'standby1'
# synchronous_commit = remote_apply

# Archiwum WAL (opcjonalne, dla point-in-time recovery)
archive_mode = on
archive_command = 'cp %p /var/lib/postgresql/wal_archive/%f'

# Restart PostgreSQL po zmianach
sudo systemctl restart postgresql

# ----
# Na PRIMARY: /etc/postgresql/16/main/pg_hba.conf
# Dodaj linię zezwalająca standy na relikację:
# TYPE  DATABASE        USER            ADDRESS                 METHOD
replication   replicator      192.168.1.11/32         scram-sha-256
# (192.168.1.11 = IP serwera standby)

# Utwórz uzytkownika replikacji
sudo -u postgres psql -c "
CREATE USER replicator WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'strong_repl_pass';
"

# Przeladuj konfiguracje pg_hba bez restartu
sudo -u postgres psql -c "SELECT pg_reload_conf();"

Replication slot — gwarancja zachowania WAL

# Na PRIMARY: stworzenie physical replication slot
sudo -u postgres psql -c "
SELECT pg_create_physical_replication_slot('standby1_slot');
"

# Sprawdz dostepne sloty
sudo -u postgres psql -c "SELECT * FROM pg_replication_slots;"
# slot_name    | active | wal_status | safe_wal_size
# standby1_slot| f      | reserved   | ...

# Monitorowanie uzytych slotow (pilnuj zeby wal_status != "lost")
sudo -u postgres psql -c "
SELECT slot_name, active, restart_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag
FROM pg_replication_slots;
"

# UWAGA: jezeli standby jest offline i slot nie jest uzywany,
# primary bedzie trzymal WAL w nieskonczonosc i moze zapelnic dysk!
# Usun slot jezeli standby jest trwale offline:
# SELECT pg_drop_replication_slot('standby1_slot');

Konfiguracja standby — pg_basebackup i recovery

# Na STANDBY: instalacja PostgreSQL (ta sama wersja co primary)
sudo apt install postgresql-16 -y
sudo systemctl stop postgresql

# Usuniecie domyslnych danych (zastapione przez pg_basebackup)
sudo rm -rf /var/lib/postgresql/16/main/*

# Klonowanie primary przez pg_basebackup
# -h = host primary, -U = uzytkownik replikacji, -P = progress, -v = verbose
# -R = automatycznie tworzy standby.signal i primary_conninfo
# -S = uzyj replication slot

sudo -u postgres pg_basebackup \
  -h 192.168.1.10 \
  -U replicator \
  -D /var/lib/postgresql/16/main \
  -P -v -R \
  -S standby1_slot \
  --checkpoint=fast

# pg_basebackup automatycznie stworzyl:
# - standby.signal (plik sygnalizujacy standby mode)
# - postgresql.auto.conf z primary_conninfo

# Sprawdz wygenerowana konfiguracje
cat /var/lib/postgresql/16/main/postgresql.auto.conf
# primary_conninfo = 'host=192.168.1.10 port=5432 user=replicator password=... sslmode=prefer'
# primary_slot_name = 'standby1_slot'

# Uruchom standby
sudo systemctl start postgresql

# Sprawdz czy standby sie polaczyl (na standby)
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"  -- powinno zwrocic 't'

# Na PRIMARY: sprawdz polaczone repliki
sudo -u postgres psql -c "SELECT * FROM pg_stat_replication;"

Monitoring opóźnienia replikacji

# Na PRIMARY: szczegolowy status replikacji
sudo -u postgres psql -c "
SELECT
  application_name,
  client_addr,
  state,
  write_lag,
  flush_lag,
  replay_lag,
  sync_state
FROM pg_stat_replication;
"

# Na STANDBY: ile czasu za primary
sudo -u postgres psql -c "
SELECT
  now() - pg_last_xact_replay_timestamp() AS replication_delay,
  pg_is_in_recovery() AS is_standby,
  pg_last_wal_replay_lsn() AS last_replayed_lsn;
"

# Skrypt monitoringu (mozna uzywac z Nagios/Zabbix)
#!/bin/bash
LAG=$(sudo -u postgres psql -t -c \
  "SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp()))::int" 2>/dev/null)
THRESHOLD=30  # sekundy

if [ "$LAG" -gt "$THRESHOLD" ]; then
  echo "CRITICAL: Replication lag = ${LAG}s (threshold: ${THRESHOLD}s)"
  exit 2
fi
echo "OK: Replication lag = ${LAG}s"
exit 0

Failover — ręczny i automatyczny z Patroni

# --- RECZNIE FAILOVER (PostgreSQL 12+) ---

# Na STANDBY: promocja do primary
sudo -u postgres psql -c "SELECT pg_promote();"
# lub:
sudo -u postgres touch /tmp/promote_trigger
# (jezeli skonfigurowano promote_trigger_file w postgresql.conf)

# Sprawdz ze standby jest teraz primary
sudo -u postgres psql -c "SELECT pg_is_in_recovery();"
# Powinno zwrocic 'f' (false = jest primary)

# Stary primary (jezeli wracamy po naprawie) — zresetuj jako standby
# OPCJA 1: pg_rewind (szybkie, wymaga ze old_primary ma wal_log_hints = on)
sudo -u postgres pg_rewind \
  --target-pgdata=/var/lib/postgresql/16/main \
  --source-server='host=192.168.1.11 user=replicator password=strong_repl_pass dbname=postgres'

# OPCJA 2: pg_basebackup od nowa (wolniejsze, zawsze dziala)
sudo -u postgres pg_basebackup -h 192.168.1.11 -U replicator -D /tmp/pgdata_new -P -R

# --- PATRONI — automatyczny failover z DCS ---
# Patroni uzywa etcd lub Consul do leader election
# Instalacja: sudo pip3 install patroni[etcd]
# Konfiguracja: /etc/patroni/patroni.yml

# Po failerze Patroni automatycznie:
# 1. Wykrywa niedostepnosc primary (health check co 10s)
# 2. Przeprowadza elekcje lidera przez etcd
# 3. Promuje najlepszy standby
# 4. Informuje przez REST API o zmianie

# Sprawdz status Patroni
patronictl -c /etc/patroni/patroni.yml list
# + Cluster: postgres-prod (123456789) --------+
# | Member    | Host          | Role    | State   |
# | pg-node1  | 192.168.1.10  | Replica | running |
# | pg-node2  | 192.168.1.11  | Leader  | running |

Najczęstsze pytania

Czym jest PostgreSQL Streaming Replication? +
Streaming Replication to wbudowany mechanizm replikacji PostgreSQL (od wersji 9.0), w którym standby (replika) pobiera zmiany z primary (mastera) w czasie rzeczywistym przez strumień WAL (Write-Ahead Log). Standby jest ciągłym kopią primary — może służyć do odczytów (hot standby) lub być gotowy do przejęcia roli primary podczas awarii (failover). Jest to replikacja fizyczna: kopiuje bloki danych, nie zapytania SQL.
Co to są replication slots w PostgreSQL? +
Replication slots to mechanizm gwarantujący, że primary nie usunie plików WAL dopóki wszystkie repliki z aktywnym slotem ich nie przetworzą. Bez slotów, jeśli replika jest offline przez długi czas, primary może usunąć potrzebne WAL pliki i replika musi być odtworzona od zera (pg_basebackup). Wada slotów: jeśli replika jest trwale offline, primary nieograniczenie gromadzi WAL i może skończyć się miejsce na dysku. Monitoruj pg_replication_slots.
Jak sprawdzić opóźnienie replikacji PostgreSQL? +
Na primary: SELECT * FROM pg_stat_replication; — pokaże write_lag, flush_lag, replay_lag dla każdej repliki. Na standby: SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay; — czas od ostatnio przetworzonej transakcji. Dopuszczalne opóźnienie zależy od wymagań — dla read repliki kilka sekund jest OK, dla repliki używanej do failover powinno być poniżej 1 sekundy.
Jak przeprowadzić failover PostgreSQL? +
Ręczny failover: na standby uruchom pg_promote() (PostgreSQL 12+) lub utwórz plik trigger_file (stare wersje). Standby staje się nowym primary. Następnie zmień connection string w aplikacji na nowy primary. Stary primary (jeśli wróci) musi być zresetowany jako standby przez pg_rewind lub pg_basebackup. Dla automatycznego failover użyj narzędzi takich jak Patroni (etcd/Consul backend), Repmgr lub pg_auto_failover.

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.