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

pgBouncer — connection pooling dla PostgreSQL

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

PostgreSQL jest wyjątkowo zasobożerny jeśli chodzi o połączenia — każde zajmuje osobny proces systemowy z kilkoma megabajtami RAM. Aplikacja webowa obsługująca 500 równoczesnych użytkowników może generować setki połączeń do bazy, co szybko przeciąża nawet mocny serwer. pgBouncer rozwiązuje ten problem utrzymując małą pulę rzeczywistych połączeń do PostgreSQL i multipleksując do nich wszystkich klientów aplikacji. Wynik: 10-krotnie więcej obsługiwanych klientów, mniejsze zużycie RAM, niższe latency pod obciążeniem.

Instalacja pgBouncer

pgBouncer jest dostępny w standardowych repozytoriach Ubuntu/Debian. Działa jako proxy między aplikacją a PostgreSQL — aplikacja łączy się z pgBouncer (port 6432), a pgBouncer utrzymuje połączenia do Postgresa (port 5432).

# Ubuntu / Debian
sudo apt update && sudo apt install pgbouncer -y

# Sprawdz wersje
pgbouncer --version

# Konfiguracja w:
# /etc/pgbouncer/pgbouncer.ini  — glowna konfiguracja
# /etc/pgbouncer/userlist.txt   — uzytkownik + haslo (MD5 lub SCRAM)

sudo systemctl enable pgbouncer
sudo systemctl start pgbouncer
sudo systemctl status pgbouncer

Konfiguracja — pgbouncer.ini

Główny plik konfiguracyjny /etc/pgbouncer/pgbouncer.ini — kluczowe sekcje to [databases] (mapowanie baz) i [pgbouncer] (parametry puli):

[databases]
; Format: alias = host=... port=... dbname=...
; Aplikacja laczy sie jako "myapp" → pgBouncer proxy do lokalnego Postgresa
myapp = host=127.0.0.1 port=5432 dbname=myapp

; Mozna mapowac wiele baz
analytics = host=127.0.0.1 port=5432 dbname=analytics_db

; Wildcard — wszystkie bazy przez pgBouncer
; * = host=127.0.0.1 port=5432

[pgbouncer]
; Adres nasluchu (aplikacja laczy sie tutaj)
listen_addr = 127.0.0.1
listen_port = 6432

; Plik z uzytkownikami i haslem
auth_file = /etc/pgbouncer/userlist.txt
auth_type = md5

; TRYB PULI — kluczowy parametr
; session     = polaczenie Postgresa trzymane przez cala sesje klienta
; transaction = polaczenie zwracane po COMMIT/ROLLBACK (ZALECANY)
; statement   = zwracane po kazdym pojedynczym zapytaniu (zaawansowane)
pool_mode = transaction

; Maks. polaczen od klientow (wszystkich razem)
max_client_conn = 1000

; Domyslny rozmiar puli per (baza, uzytkownik)
default_pool_size = 20

; Zapas polaczen przy skoku ruchu
reserve_pool_size = 5
reserve_pool_timeout = 3

; Czas oczekiwania klienta na wolne polaczenie (sekundy)
; Po tym czasie klient dostaje blad
client_login_timeout = 60

; Logi
log_connections = 0
log_disconnections = 0
log_pooler_errors = 1

; Dostep do bazy statystyk pgbouncer (do monitorowania)
stats_users = stats, pgbouncer

Konfiguracja userlist.txt i pg_hba.conf

pgBouncer uwierzytelnia klientów samodzielnie (na podstawie userlist.txt), a następnie łączy się z PostgreSQL jako zdefiniowany użytkownik. Hasła w userlist.txt muszą być zahashowane MD5 w formacie md5 + MD5(haslo + uzytkownik):

# Generuj hash MD5 dla uzytkownika "appuser" z haslem "tajnehaslo"
echo -n "tajnehasloappuser" | md5sum
# Wynik: abc123... (32 znaki)

# /etc/pgbouncer/userlist.txt — format: "uzytkownik" "md5HASH"
"appuser" "md5abc123def456..."
"stats"   "md5xyz789..."

# Alternatywnie: skopiuj hash z PostgreSQL
psql -U postgres -c "SELECT usename, passwd FROM pg_shadow WHERE usename='appuser';"
# /etc/postgresql/15/main/pg_hba.conf
# Zezwol na polaczenia od pgBouncer (127.0.0.1 lub dedykowany IP)
# TYPE  DATABASE  USER      ADDRESS       METHOD
host    myapp     appuser   127.0.0.1/32  md5
host    all       stats     127.0.0.1/32  md5

# Reload PostgreSQL po zmianach
sudo systemctl reload postgresql

# Restart pgBouncer po zmianach konfiguracji
sudo systemctl restart pgbouncer

Tryby pool_mode — szczegółowe porównanie

pool_mode Kiedy zwraca połączenie Gęstość multipleksowania Ograniczenia Użycie
session Koniec sesji klienta Niska (1:1) Brak (pełna kompatybilność) Migracja bez zmian w aplikacji
transaction COMMIT / ROLLBACK Wysoka (50:1) Brak SET, LISTEN, temp tables Typowe aplikacje webowe
statement Koniec każdego zapytania Bardzo wysoka Brak transakcji multi-statement Read-only analytics, cache warmup

Uwaga dla transaction mode: Jeśli Twoja aplikacja używa SET search_path, SET LOCAL, LISTEN/NOTIFY, prepared statements z PREPARE lub tymczasowych tabel — potrzebujesz obejść to przez server_reset_query lub przełączyć na session mode.

Połączenie z aplikacji przez pgBouncer

Aplikacja łączy się z pgBouncer dokładnie tak samo jak z PostgreSQL — zmieniasz tylko port z 5432 na 6432:

# PHP (PDO) — tylko zmiana portu z 5432 na 6432
$pdo = new PDO('pgsql:host=127.0.0.1;port=6432;dbname=myapp', 'appuser', 'tajnehaslo');

# Python (psycopg2)
conn = psycopg2.connect(
    host='127.0.0.1',
    port=6432,
    dbname='myapp',
    user='appuser',
    password='tajnehaslo'
)

# Node.js (pg)
const pool = new Pool({
  host: '127.0.0.1',
  port: 6432,
  database: 'myapp',
  user: 'appuser',
  password: 'tajnehaslo',
  max: 10  // Pool w aplikacji — dodatkowa warstwa
});

# Django settings.py
DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'HOST': '127.0.0.1',
    'PORT': '6432',
    'NAME': 'myapp',
    'USER': 'appuser',
    'PASSWORD': 'tajnehaslo',
  }
}

Monitoring — SHOW POOLS i SHOW STATS

pgBouncer udostępnia wirtualną bazę pgbouncer na tym samym porcie do monitorowania stanu puli. Połącz się jako użytkownik stats:

# Polacz sie do konsoli statystyk
psql -h 127.0.0.1 -p 6432 -U stats pgbouncer

-- Stan pul polaczen
SHOW POOLS;
-- database | user    | cl_active | cl_waiting | sv_active | sv_idle | maxwait
-- myapp    | appuser | 45        | 0          | 18        | 2       | 0

-- Statystyki ruchu
SHOW STATS;
-- database | total_xact_count | total_query_count | avg_xact_duration_us

-- Aktywni klienci
SHOW CLIENTS;

-- Polaczenia do PostgreSQL
SHOW SERVERS;

-- Konfiguracja live
SHOW CONFIG;

-- Przeladuj konfiguracje bez restartu
RELOAD;

-- Zatrzymaj przyjmowanie nowych polaczen (graceful)
PAUSE myapp;
RESUME myapp;
Metryka Znaczenie Alert gdy
cl_active Klienci aktywnie wykonujący zapytanie Zbliża się do max_client_conn
cl_waiting Klienci czekający na wolne połączenie Wartość > 0 przez więcej niż kilka sekund
sv_active Połączenia do Postgresa z aktywnym zapytaniem Równa pool_size = brak rezerwy
sv_idle Wolne połączenia w puli Stale 0 = pool za mały
maxwait Najdłuższy czas oczekiwania klienta (s) Wartość > 1s = problem z rozmiarem puli

Dobieranie rozmiaru puli — reguły kciuka

  • default_pool_size — zacznij od liczby rdzeni CPU serwera PostgreSQL (np. 4-rdzeniowy = pool 4-8). Zwiększaj stopniowo obserwując cl_waiting.
  • max_client_conn — ile klientów (aplikacji) może jednocześnie trzymać połączenie z pgBouncer. Może być 10-100× większe niż default_pool_size.
  • PostgreSQL max_connections — musi być > suma pool_size wszystkich baz + połączenia administracyjne. Formuła: max_connections = sum(pool_sizes) + 10.
  • server_idle_timeout — jak długo pgBouncer trzyma nieużywane połączenie do Postgresa (domyślnie 600s). Zmniejsz do 60-120s jeśli baza ma restrykcyjny limit.
  • Wiele pul — każda para (baza, użytkownik) ma osobną pulę. Jeśli masz wiele użytkowników bazy, sumuj ich pool_size przy planowaniu max_connections.

Najczęstsze pytania

Do czego służy pgBouncer i kiedy go potrzebuję? +
pgBouncer to lekki connection pooler dla PostgreSQL. PostgreSQL tworzy osobny proces systemowy na każde połączenie klienta (nawet 5 MB RAM per connection). Przy 1000 równoczesnych klientów (typowe dla aplikacji webowych) oznacza to 5 GB RAM tylko na procesy połączeń. pgBouncer utrzymuje mały basen rzeczywistych połączeń do Postgresa (np. 20) i multipleksuje do nich liczne równoczesne sesje klientów. Wymagany gdy: masz dużo krótko-żyjących połączeń (PHP-FPM, serverless), widzisz błędy "too many connections", latency rośnie pod obciążeniem.
Jaka jest różnica między pool_mode transaction, session i statement? +
Session mode: połączenie z Postgresem jest przypisane klientowi na czas całej sesji (bezpieczny, ale słabo multipleksuje — jak bez poolera). Transaction mode: połączenie jest zwracane do puli po COMMIT/ROLLBACK — pozwala 1000 klientom współdzielić 20 połączeń. Najczęściej używany. Ograniczenie: SET/LISTEN/NOTIFY, temporary tables, advisory locks nie działają między transakcjami. Statement mode: zwraca po każdym pojedynczym zapytaniu — maksymalna gęstość puli, ale nie obsługuje multi-statement transakcji. Tylko dla prostych read-only workloadów.
Czy pgBouncer zastępuje połączenie pool w aplikacji (np. connection pool w Node.js)? +
Nie zastępuje, ale uzupełnia. Pool w aplikacji (np. pg w Node.js, SQLAlchemy w Pythonie) utrzymuje połączenia w ramach jednego procesu i redukuje koszt nawiązywania połączeń z aplikacji. pgBouncer działa na poziomie sieci i konsoliduje połączenia z WIELU instancji aplikacji (np. 10 podów Node.js × 10 połączeń = 100 → pgBouncer mapuje je na 20 rzeczywistych). Kombinacja obu daje najlepszy wynik: pool w aplikacji dla lokalnej wydajności + pgBouncer dla globalnej konsolidacji.
Jak monitorować pgBouncer i skąd wiedzieć że działa poprawnie? +
Połącz się do bazy pgbouncer (port 6432, użytkownik stats): psql -p 6432 -U stats pgbouncer. Komendy: SHOW POOLS (cl_active, cl_waiting, sv_active, sv_idle, sv_tested), SHOW STATS (total_requests, total_received, avg_query_duration), SHOW CLIENTS, SHOW SERVERS. Kluczowe metryki: cl_waiting > 0 znaczy klienci czekają na wolne połączenie (zwiększ pool_size lub dodaj serwery), avg_query_duration rośnie = wolne zapytania lub przeciążony Postgres.

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.