PostgreSQL na VPS: jak dobrać pamięć i dysk

Szybka baza PostgreSQL to baza, w której często odczytywane dane mieszczą się w pamięci. Od tego zależy cały dobór: rozmiar bazy, część, która naprawdę pracuje, liczba połączeń, a potem dysk i jego zapas. Ten poradnik podaje metodę, ustawienia początkowe dla 4, 8 i 16 GB pamięci oraz zapytania, które mierzą istniejącą bazę.

Opublikowano 29 października 2026 Autor: Czas czytania: 10 minut

Wszystkie poradniki

W skrócie

  1. Proszę zmierzyć rozmiar bazy i jej indeksów, a potem część odczytywaną często: to ona musi zmieścić się w pamięci.
  2. Punkt wyjścia: shared_buffers na 25 % pamięci, effective_cache_size na 75 %, random_page_cost = 1.1 na SSD NVMe.
  3. Każde połączenie to proces: powyżej kilkudziesięciu aktywnych połączeń proszę umieścić PgBouncer przed bazą.
  4. Dysk: dane i indeksy za rok, plus co najmniej 30 % zapasu. Pełny dysk zatrzymuje PostgreSQL.
  5. Współczynnik trafień w pamięci podręcznej powinien pozostawać powyżej 99 %: poniżej tej wartości bazie brakuje pamięci.
  6. Proszę codziennie wykonywać kopię przez pg_dump, poza serwerem, i regularnie ją przywracać, aby to sprawdzić.

Punkt wyjścia: ilość używanych danych

Pamięć serwera bazy danych służy przede wszystkim jako pamięć podręczna: strona odczytana z pamięci jest serwowana znacznie szybciej niż strona odczytana z dysku, nawet NVMe. Pytanie brzmi więc nie tylko „ile waży baza?”, ale także „jaka jej część jest często odczytywana?”. Baza o rozmiarze 50 GB, w której odpytywane jest tylko ostatnie dwanaście miesięcy, pracuje być może na 8 GB.

Na istniejącej bazie dwa zapytania podają rozmiar całkowity i największe tabele, łącznie z indeksami:

SQL (psql)
SELECT pg_size_pretty(pg_database_size(current_database()));

SELECT relname AS nom,
       pg_size_pretty(pg_total_relation_size(relid)) AS taille_avec_index
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;

Dla bazy, która dopiero powstanie, proszę szacować tabela po tabeli: liczba wierszy oczekiwana za rok × średni rozmiar wiersza, a następnie dodać indeksy, które ważą zwykle od 30 do 100 % danych. Przykład: 2 miliony wierszy miesięcznie, po 500 bajtów każdy, dają za rok 12 GB danych, a z indeksami od 18 do 24 GB.

Pamięć: ustawienia początkowe

PostgreSQL przechowuje odczytane strony na dwóch poziomach: we własnej pamięci podręcznej (shared_buffers) i w pamięci podręcznej plików systemu. Jego dokumentacja zaleca, aby na serwerze przeznaczonym wyłącznie dla bazy zacząć od 25 % pamięci dla shared_buffers, i zauważa, że powyżej 40 % zysk pojawia się rzadko: reszta służy pamięci podręcznej systemu i sortowaniu.

Parametr4 GB8 GB16 GBRola
shared_buffers1 GB2 GB4 GBWłasna pamięć podręczna PostgreSQL
effective_cache_size3 GB6 GB12 GBSzacowana łączna pamięć podręczna, która wpływa na wybór planów zapytań
work_mem8 MB16 MB32 MBPamięć każdego sortowania lub haszowania, na połączenie: do pomnożenia przez liczbę jednoczesnych zapytań
maintenance_work_mem256 MB512 MB1 GBTworzenie indeksów i VACUUM
random_page_cost1.11.11.1Szacowany koszt odczytu losowego: domyślnie 4, znacznie powyżej rzeczywistego kosztu na SSD NVMe

Te wartości zakładają, że baza działa na serwerze sama. Jeśli obok działa aplikacja, proszę najpierw odjąć jej pamięć (procesy, pamięć podręczna, kompilacja) i zastosować procenty do reszty: serwer 8 GB, na którym działa aplikacja zajmująca 3 GB, konfiguruje się jak bazę dysponującą 5 GB.

postgresql.conf, dla serwera 8 GB przeznaczonego wyłącznie dla bazy
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 16MB
maintenance_work_mem = 512MB
random_page_cost = 1.1

shared_buffers zaczyna obowiązywać dopiero po restarcie PostgreSQL; pozostałe parametry przeładowuje się bez przerwy w działaniu, przez SELECT pg_reload_conf();.

Aby sprawdzić, czy pamięci wystarcza, proszę odczytać współczynnik trafień w pamięci podręcznej. W aplikacji biznesowej lub na stronie internetowej przekracza on 99 %:

SQL (psql)
SELECT round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS taux_cache
FROM pg_stat_database
WHERE datname = current_database();

Połączenia: każde to osobny proces

PostgreSQL otwiera jeden proces na połączenie i domyślnie przyjmuje ich 100 (max_connections). Każdy proces zajmuje kilka megabajtów w spoczynku, więcej, gdy sortuje lub haszuje dane (work_mem, czasem kilka razy w jednym zapytaniu). Podniesienie max_connections do 500, aby nadążyć za aplikacją, która otwiera wiele połączeń, naraża serwer na brak pamięci przy pierwszym szczycie.

Właściwą odpowiedzią jest pula połączeń: PgBouncer w trybie transaction pozwala setkom połączeń aplikacji współdzielić kilkadziesiąt rzeczywistych połączeń. Frameworki mają też własną pulę (SQLAlchemy, Prisma, HikariCP): jej rozmiar proszę dopasować do liczby vCPU serwera bazy, a nie do liczby użytkowników.

Dysk: rozmiar, zapas i dziennik

Dysk serwera PostgreSQL przechowuje więcej niż tabele:

Zasada: rozmiar za rok plus co najmniej 30 % zapasu. To nie kwestia wygody: gdy dysk z dziennikiem transakcji się zapełni, PostgreSQL zatrzymuje się, aby chronić swoje dane. Proszę obserwować zajętość i powiększać dysk przed osiągnięciem 80 %.

Jeśli chodzi o wydajność, każde zatwierdzenie transakcji czeka na zapis dziennika na dysk: opóźnienie pamięci masowej wyznacza przepustowość zapisu. Tu SSD NVMe robi różnicę, znacznie większą niż przy odczytach, które obsługuje już pamięć.

Procesor: jedno zapytanie, jeden rdzeń

Zapytanie PostgreSQL wykonuje się na jednym rdzeniu, z wyjątkiem dużych odczytów, które silnik zrównolegla. Liczba vCPU wyznacza więc liczbę ciężkich zapytań przetwarzanych jednocześnie: 2 vCPU wystarczają aplikacji biznesowej na start, od 4 do 8 sprawdza się przy mocno obciążonych bazach i ciężkich raportach.

Zanim dodadzą Państwo vCPU, proszę znaleźć zapytania, które je zużywają. Rozszerzenie pg_stat_statements szereguje je według łącznego czasu:

postgresql.conf, potem restart
shared_preload_libraries = 'pg_stat_statements'
SQL (psql)
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT calls, round(total_exec_time) AS ms_total,
       round(mean_exec_time::numeric, 1) AS ms_moyen, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Ten sam serwer co aplikacja czy osobny?

Na start baza na tym samym serwerze co aplikacja to dobry wybór: brak opóźnień sieciowych między nimi, połączenie przez gniazdo Unix, jeden serwer do archiwizacji i nadzoru. Rozdziela się je, gdy rywalizują o zasoby: kompilacja lub szczyt ruchu, który opróżnia pamięć podręczną bazy, baza, która potrzebuje całej pamięci na swoje dane, albo różne wymagania dotyczące kopii zapasowych.

Bezpieczeństwo i kopie zapasowe

Terminal: skompresowany eksport, a potem przywrócenie do testowej bazy
pg_dump -Fc -d moja_baza -f moja_baza-$(date +%F).dump
createdb moja_baza_test
pg_restore -d moja_baza_test moja_baza-2026-10-29.dump

Szybka baza PostgreSQL na właściwym serwerze

VPS Pro działa na procesorach Intel Xeon, pamięci ECC, która koryguje błędy w locie, i SSD NVMe w konfiguracji lustrzanej, z każdym blokiem danych weryfikowanym sumą kontrolną i szyfrowaną kopią zapasową co noc, przechowywaną poza maszyną. Kompleksowe wsparcie jest w cenie: gdy Państwa baza zwalnia, analizujemy wolne zapytania i indeksy, a następnie wskazujemy ustawienia, które przywracają Państwa aplikacji pełną szybkość.

Poznaj VPS Pro

Częste pytania

Ile RAM potrzebuje PostgreSQL?

Tyle, aby często odczytywane dane mieściły się w pamięci. Dla aplikacji biznesowej na start wystarczają 4 GB, łącznie z bazą i aplikacją. Potem proszę mierzyć współczynnik trafień w pamięci podręcznej: dopóki pozostaje powyżej 99 %, pamięci wystarcza.

Jaką wartość ustawić dla shared_buffers?

25 % pamięci na serwerze przeznaczonym wyłącznie dla bazy, zgodnie z zaleceniem dokumentacji PostgreSQL: 1 GB przy 4 GB, 2 GB przy 8 GB, 4 GB przy 16 GB. Powyżej 40 % zysk pojawia się rzadko, bo resztę robi pamięć podręczna systemu.

Ile połączeń PostgreSQL może przyjąć VPS?

PostgreSQL domyślnie przyjmuje 100 połączeń, a każde z nich to proces, który zużywa pamięć. Zamiast podnosić ten limit, lepiej umieścić przed bazą pulę połączeń, taką jak PgBouncer: kilkadziesiąt rzeczywistych połączeń obsługuje wtedy setki połączeń aplikacji.

Czy bazę danych trzeba oddzielić od aplikacji?

Nie na start: na tym samym serwerze baza odpowiada bez opóźnień sieciowych, a całość archiwizuje się za jednym razem. Rozdziela się je, gdy jedna przeszkadza drugiej, na przykład gdy kompilacja lub szczyt ruchu opróżnia pamięć podręczną bazy.

Skontaktuj się z nami