Instalacja i konfiguracja PostgreSQL na Debianie i Ubuntu
Instalacja z pakietu dystrybucji albo z repozytorium PGDG, pierwszy dostęp przez użytkownika postgres, tworzenie bazy i roli, zrozumienie pg_hba.conf oraz kopia zapasowa, która naprawdę działa.
PostgreSQL instaluje się na Debianie i Ubuntu w dwie minuty. Pozostałe dwie godziny schodzą zwykle na tym, że nikt nie potrafi się zalogować. Ten artykuł doprowadza instalację do końca: wybór pakietu, pierwszy dostęp, baza danych i użytkownik, reguły dostępu w pg_hba.conf oraz kopia zapasowa, o której wiadomo, że da się ją odtworzyć.
Wszystkie polecenia uruchamiasz jako root. Jeśli logujesz się jako zwykły użytkownik, dopisz na początku sudo. Numer wersji 17 w ścieżkach zamień na wersję, która faktycznie jest zainstalowana w twoim systemie.
Która wersja PostgreSQL trafia do której dystrybucji
Najważniejsza różnica między czterema popularnymi systemami to wersja główna, która przychodzi z repozytorium dystrybucji. Jest na stałe związana z wydaniem i przez cały okres życia dystrybucji już się nie zmienia.
| Dystrybucja | PostgreSQL z repozytorium dystrybucji |
| Debian 13 (trixie) | 17 |
| Debian 12 (bookworm) | 15 |
| Ubuntu 24.04 LTS (noble) | 16 |
| Ubuntu 22.04 LTS (jammy) | 14 |
Ten rozrzut ma praktyczne konsekwencje. Dumpa z Debiana 13 nie wgrasz tak po prostu do Ubuntu 22.04. A jeśli pracujesz na Ubuntu 22.04, warto wiedzieć, że zgodnie z polityką wersjonowania PostgreSQL Global Development Group wersja 14 wypada ze wsparcia społeczności 12 listopada 2026. Ubuntu nadal dostarcza dla 22.04 aktualizacje bezpieczeństwa w ramach cyklu LTS, ale poprawki z upstreamu już nie napływają. Przy nowych projektach na 22.04 to mocny argument, żeby od razu sięgnąć po repozytorium PGDG.
Co jest dostępne w twoim systemie, sprawdzisz w bazie pakietów, zanim cokolwiek zainstalujesz:
apt update
apt-cache policy postgresql
Wiersz Kandydująca, po angielsku Candidate, pokazuje numer wersji w rodzaju 17+283. Liczba przed plusem to wersja główna PostgreSQL, reszta to numer wersji metapakietu Debiana.
Instalacja z pakietu dystrybucji
W większości zastosowań pakiet z dystrybucji jest właściwym wyborem. Jest objęty aktualizacjami bezpieczeństwa dystrybucji, współpracuje z bibliotekami systemu i nie sprawia problemów przy podniesieniu wersji systemu.
apt install -y postgresql postgresql-contrib
postgresql-contrib dokłada rozszerzenia dostarczane razem z serwerem, w tym pgcrypto, uuid-ossp i pg_stat_statements. Bez tego pakietu wiele aplikacji wykłada się później na ERROR: could not open extension control file, a szukanie przyczyny trwa dłużej niż sama instalacja.
Debian i Ubuntu podczas instalacji automatycznie zakładają pierwszy klaster o nazwie main i uruchamiają go. Klaster oznacza tutaj działającą instancję z własnym katalogiem danych, własnym portem i własną konfiguracją. Czy się udało, nie odpowiada kod wyjścia polecenia apt, tylko to:
pg_lsclusters
W kolumnie Status musi pojawić się online:
Ver Cluster Port Status Owner Data directory Log file
17 main 5432 online postgres /var/lib/postgresql/17/main /var/log/postgresql/postgresql-17-main.log
Jeśli widnieje tam down, dostartuj usługę. service postgresql start działa na wszystkich czterech systemach, również w kontenerach bez systemd. Na zwykłym serwerze tak samo dobrze zadziała systemctl start postgresql.
service postgresql start
pg_isready
pg_isready odpowiada komunikatem /var/run/postgresql:5432 - accepting connections i zwraca kod wyjścia 0. To pierwszy twardy dowód, że serwer jest osiągalny, i da się go wykorzystać w skryptach monitorujących.
Kiedy warto sięgnąć po repozytorium PGDG i jak je poprawnie podpiąć
Oficjalne repozytorium pod adresem apt.postgresql.org udostępnia równolegle wszystkie wspierane wersje główne dla trixie, bookworm, noble i jammy. To właściwy wybór, gdy potrzebujesz konkretnej wersji głównej, bo wymaga jej aplikacja, gdy potrzebujesz rozszerzeń, których Debian nie pakietuje, albo gdy twoja dystrybucja wskazuje na wersję, która niedługo wypadnie ze wsparcia.
Klucz trafia do własnego pliku, a nie do wycofanej bazy kluczy apt-key. Debian 13 i Ubuntu 24.04 preferują poza tym format deb822 z rozszerzeniem .sources, który działa jednak także na Debianie 12 i Ubuntu 22.04:
apt install -y curl ca-certificates
install -d /usr/share/postgresql-common/pgdg
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
cat > /etc/apt/sources.list.d/pgdg.sources <<EOF
Types: deb
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: $(. /etc/os-release && echo $VERSION_CODENAME)-pgdg
Components: main
Signed-By: /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
EOF
Wiersz z $(. /etc/os-release ...) automatycznie wstawia trixie-pgdg, bookworm-pgdg, noble-pgdg albo jammy-pgdg. Następnie:
apt update
apt-cache policy postgresql-18
Pakiet postgresql-common dostarcza do tego samego celu gotowy skrypt /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh. Jest on alternatywą dla klucza i pliku pgdg.sources z góry, a nie ich uzupełnieniem. Jeśli wykonasz jedno i drugie, skrypt założy dodatkowo /etc/apt/sources.list.d/pgdg.list, a apt będzie potem przy każdym uruchomieniu ostrzegał: W: Target Packages (main/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list.d/pgdg.list:1 and /etc/apt/sources.list.d/pgdg.sources:1. Jeśli wolisz skrypt od powyższych kroków, doinstaluj wcześniej gnupg, czyli apt install -y curl ca-certificates gnupg. Starsza wersja skryptu na Ubuntu 22.04 importuje bowiem klucz jeszcze przez apt-key i bez gnupg przerywa pracę komunikatem E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation oraz kodem wyjścia 255. Na Debianie 13, Debianie 12 i Ubuntu 24.04 nowsza wersja zapisuje klucz bezpośrednio jako .asc i przechodzi bez dodatkowego pakietu.
Pułapka: dwa klastry, dwa porty
Jeśli na systemie z już zainstalowanym pakietem dystrybucji dołożysz teraz nową wersję główną, powstanie drugi klaster. Nie dostanie on portu 5432, tylko następny wolny, czyli 5433. Aplikacje nadal łączą się ze starą wersją i żaden komunikat błędu tego nie zdradza. To najczęstsza przyczyna zdania „przecież zainstalowałem PostgreSQL 18, a SELECT version() pokazuje 15”.
apt install -y postgresql-18
pg_lsclusters
Teraz widnieją tam dwa wiersze z różnymi portami. Jeśli chcesz przenieść dane do nowej wersji, właściwym narzędziem jest pg_upgradecluster, a nie ręczny dump. Wymaga ono, żeby oba pakiety serwera były zainstalowane, i zostawia stary klaster zatrzymany, zamiast go usuwać:
pg_upgradecluster 15 main
Sprawdź potem poleceniem pg_lsclusters, który klaster siedzi na porcie 5432, i przetestuj aplikację, zanim ostatecznie usuniesz stary klaster przez pg_dropcluster --stop 15 main. To polecenie kasuje katalog danych bez pytania o potwierdzenie.
Pierwszy dostęp i dlaczego root nie uruchomi psql
Klasyczna przeszkoda zaraz po instalacji:
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: role "root" does not exist
To nie jest błąd, tylko oczekiwane zachowanie. Debian i Ubuntu konfigurują lokalne połączenia przez socket metodą peer. PostgreSQL pyta wtedy jądro, na którym użytkowniku systemowym otwarto połączenie, i wymaga, żeby istniała rola bazodanowa o tej samej nazwie. Istnieje tylko rola postgres, więc najpierw musisz przełączyć się na tego użytkownika systemowego.
su - postgres
Potem uruchamiasz psql bez argumentów. Do wyjścia z shella służy exit. Przy pojedynczych poleceniach wywoływanych ze skryptu wygodniejsze jest przełączenie użytkownika osobno dla każdego polecenia:
runuser -u postgres -- psql -c "SELECT version();"
Jeśli masz zainstalowane sudo, napiszesz zamiast tego sudo -u postgres psql -c "SELECT version();". Obie wersje są równoważne. Przy sudo często pojawia się ostrzeżenie could not change directory to "/root": Permission denied. Jest ono bez znaczenia, bo użytkownik postgres nie ma prawa wejść do katalogu roboczego roota, ale polecenie i tak zostaje wykonane.
Te trzy zapytania mówią ci, z czym masz do czynienia, i są pierwszym krokiem przy każdym szukaniu błędu:
runuser -u postgres -- psql -c "SHOW server_version;"
runuser -u postgres -- psql -c "SHOW config_file;"
runuser -u postgres -- psql -c "SHOW hba_file;"
Ostatnie polecenie jest szczególnie przydatne. Podaje ścieżkę, którą działający serwer naprawdę czyta, zwykle /etc/postgresql/17/main/pg_hba.conf. Jeśli edytujesz plik, a nic się nie zmienia, prawie zawsze masz przed sobą konfigurację innego klastra.
Wewnątrz psql pomagają metapolecenia: \l wypisuje bazy danych, \du role, \dt tabele bieżącej bazy, \conninfo pokazuje, jako kto i dokąd jesteś podłączony, a \q kończy sesję.
Tworzenie bazy danych i użytkownika
Dla każdej aplikacji zakładaj osobną rolę i osobną bazę danych. Kolejność ma znaczenie, bo baza ma od razu należeć do tej roli.
runuser -u postgres -- psql -c "CREATE ROLE appuser LOGIN PASSWORD 'TwojeSilneHaslo';"
runuser -u postgres -- psql -c "CREATE DATABASE appdb OWNER appuser;"
Od PostgreSQL 14 hasła są domyślnie zapisywane metodą scram-sha-256, dotyczy to więc wszystkich czterech omawianych tu systemów. Hasło nie ląduje wprawdzie w bazie jawnym tekstem, ale zostaje w historii twojego shella. Jeśli chcesz tego uniknąć, użyj w psql polecenia \password appuser, które pyta o hasło interaktywnie.
Pułapka od PostgreSQL 15: permission denied for schema public
Zachowanie, którego wiele starszych poradników jeszcze nie uwzględnia: od PostgreSQL 15 nie każdy użytkownik może zakładać obiekty w schemacie public. Dotyczy to Debiana 12, Debiana 13 i Ubuntu 24.04. Tylko Ubuntu 22.04 z PostgreSQL 14 zachowuje się jeszcze po staremu. Błąd wygląda tak:
ERROR: permission denied for schema public
LINE 1: CREATE TABLE klienci (id serial primary key);
Czysta droga to ta pokazana wyżej: baza należy do roli. Schemat public od wersji 15 należy do roli pg_database_owner, a właściciel danej bazy jest w niej niejawnie członkiem. Jeśli natomiast założyłeś bazę bez OWNER, nadaj uprawnienie później. Zwróć uwagę, że to polecenie musi zostać wykonane w tej właśnie bazie, a nie w postgres:
runuser -u postgres -- psql -d appdb -c "GRANT ALL ON SCHEMA public TO appuser;"
Dowód, że uprawnienia się zgadzają
CREATE ROLE bez błędu nie oznacza jeszcze, że aplikacja zdoła się zalogować. Dowodem jest prawdziwe logowanie przez TCP i następujący po nim zapis. PGPASSWORD służy tu wyłącznie do testu, do stałej pracy zobacz dalej:
PGPASSWORD='TwojeSilneHaslo' psql -h 127.0.0.1 -U appuser -d appdb -c "SELECT current_user, current_database();"
PGPASSWORD='TwojeSilneHaslo' psql -h 127.0.0.1 -U appuser -d appdb -c "CREATE TABLE probe (id int);"
Jeśli oba polecenia przejdą, komplet roli, hasła, bazy i uprawnień do schematu jest kompletny. Tabela probe zostaje celowo na miejscu, bo opisany dalej test kopii zapasowej potrzebuje przynajmniej jednego obiektu w bazie, inaczej sprawdza pustkę. Dla kontroli wypisz obiekty:
runuser -u postgres -- psql -c "\du"
runuser -u postgres -- psql -c "\l"
Słowo o kodowaniu znaków: jeśli w chwili zakładania klastra ustawienia regionalne systemu nie wskazywały na UTF-8, baza wzorcowa może mieć kodowanie SQL_ASCII. CREATE DATABASE ... ENCODING 'UTF8' kończy się wtedy błędem ERROR: new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII). Obejściem jest TEMPLATE template0 przy zakładaniu, a czystym rozwiązaniem system z ustawieniami regionalnymi w UTF-8.
Zrozumieć pg_hba.conf, najczęstsze źródło błędów
Plik pg_hba.conf (host-based authentication) decyduje jeszcze przed sprawdzeniem hasła, czy połączenie w ogóle zostanie dopuszczone. Czytany jest od góry do dołu i wygrywa pierwszy pasujący wiersz. Jeśli nie pasuje żaden, połączenie zostaje odrzucone. Hojna reguła niżej nic ci nie da, gdy ostrzejsza wyżej zadziała pierwsza. To zdecydowanie najczęstszy błąd konfiguracyjny.
Stan po instalacji na Debianie i Ubuntu wygląda tak:
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
Tak wygląda to na czterech omawianych tu systemach. Na starszych wydaniach, na przykład na Debianie 11 z PostgreSQL 13, oba wiersze host mają jeszcze md5 zamiast scram-sha-256. Logowanie przez TCP działa w obu przypadkach, ale na md5 nie powinieneś już polegać.
Znaczenie kolumn: local oznacza uniksowy socket, host połączenia TCP z TLS lub bez, a hostssl wyłącznie połączenia TLS. Dalej idą baza danych, rola, zakres sieci w zapisie CIDR i metoda. Ważne są cztery metody. peer sprawdza użytkownika systemowego i działa tylko przez socket. scram-sha-256 to nowoczesna metoda hasłowa i właściwy wybór dla wszystkiego, co idzie przez TCP. md5 jest wycofana i nie powinna się już pojawiać w nowych konfiguracjach. trust wpuszcza każdego bez sprawdzania i nie ma czego szukać na serwerze osiągalnym z sieci.
Komunikaty błędów, dosłownie
Kto raz nauczy się je rozróżniać, oszczędza sobie mnóstwa zgadywania:
FATAL: Peer authentication failed for user "appuser"
Łączysz się przez socket, ale twój użytkownik systemowy nazywa się inaczej niż rola. Albo przełącz użytkownika, albo połącz się przez -h 127.0.0.1, żeby zadziałał wiersz host.
FATAL: no pg_hba.conf entry for host "198.51.100.4", user "appuser", database "appdb", no encryption
Serwer jest osiągalny, ale żadna reguła nie pasuje do tej kombinacji adresu źródłowego, roli i bazy danych. Albo brakuje wiersza, albo sieć w istniejącym wierszu nie obejmuje tego adresu.
FATAL: password authentication failed for user "appuser"
Reguła zadziałała, ale hasło się nie zgadza. Często dlatego, że rola została założona bez LOGIN albo hasło pochodzi jeszcze z wcześniejszej instalacji.
psql: error: connection to server at "203.0.113.10", port 5432 failed: Connection refused
Tutaj pg_hba.conf w ogóle nie wszedł do gry. Albo serwer nie działa, albo nie nasłuchuje na tym adresie, albo blokuje firewall. O tym za chwilę.
Sprawdź zmiany, zanim przeładujesz konfigurację
PostgreSQL udostępnia widok systemowy, który pokazuje sparsowane reguły wraz z numerem wiersza i błędami składni. Odpowiada on na pytanie, jaką regułę serwer faktycznie widzi, a nie jaką ci się wydaje, że napisałeś:
runuser -u postgres -- psql -c "SELECT line_number, type, database, user_name, address, auth_method FROM pg_hba_file_rules;"
Zmiany w pg_hba.conf nie wymagają restartu, wystarczy przeładowanie i nie zrywa ono istniejących połączeń:
runuser -u postgres -- psql -c "SELECT pg_reload_conf();"
Alternatywnie service postgresql reload. Prawdziwy restart jest potrzebny tylko wtedy, gdy zmieniłeś parametry takie jak listen_addresses, port czy shared_buffers.
Otwarcie dostępu z zewnątrz
Fabrycznie PostgreSQL nasłuchuje wyłącznie na localhost. To dobre ustawienie domyślne i powinieneś je porzucić tylko wtedy, gdy naprawdę trzeba. Muszą zejść się dwie rzeczy: serwer musi nasłuchiwać na danym adresie, a pg_hba.conf musi dopuszczać źródło. Jeśli brakuje pierwszego, dostajesz Connection refused, jeśli drugiego, dostajesz no pg_hba.conf entry.
Konfiguracja leży w /etc/postgresql/17/main/postgresql.conf. Debian dostarcza do tego narzędzie pg_conftool, które edytuje ten plik pewniej niż wyszukiwanie w edytorze:
pg_conftool 17 main show listen_addresses
pg_conftool 17 main set listen_addresses '10.0.0.5,127.0.0.1'
Wpisuj konkretne adresy zamiast *. Na serwerze z adresem publicznym i wewnętrznym zwiążesz w ten sposób usługę tylko z siecią wewnętrzną. Następnie dopisujesz regułę w pg_hba.conf, ujętą tak wąsko, jak to możliwe:
host appdb appuser 10.0.0.0/24 scram-sha-256
Po restarcie poleceniem service postgresql restart sprawdzasz najpierw, czego proces naprawdę słucha. ss -lntp | grep 5432 pokazuje przypisane adresy. Jeśli widnieje tam tylko 127.0.0.1:5432, zmiana nie zadziałała, najczęściej dlatego, że chodziło o drugi klaster albo plik w conf.d nadpisuje tę wartość.
Firewall również potrzebuje reguły, i to takiej ze wskazaniem źródła. Ryczałtowo otwarty port 5432 w internecie zostanie przeskanowany w ciągu kilku godzin:
ufw allow from 10.0.0.0/24 to any port 5432 proto tcp
Szczera rada: w większości przypadków lepszym rozwiązaniem jest w ogóle nie otwierać portu. Do zadań serwisowych w zupełności wystarczy tunel SSH poleceniem ssh -L 5432:127.0.0.1:5432 uzytkownik@serwer. Przy stałych połączeniach między kilkoma serwerami czystszym wyborem jest sieć WireGuard, bo baza danych nasłuchuje wtedy nadal wyłącznie na adresie prywatnym. Debian i Ubuntu włączają zresztą TLS domyślnie, z certyfikatem samopodpisanym, dlatego sslmode=require działa od razu. Prawdziwą ochronę przed napastnikiem na trasie połączenia daje jednak dopiero sslmode=verify-full z certyfikatem, któremu klient ufa.
Kopia zapasowa przez pg_dump i dowód, że jest coś warta
Dla pojedynczych baz najlepszym wyborem jest format custom. Jest skompresowany, da się go odtwarzać wybiórczo i można go wczytywać równolegle:
runuser -u postgres -- pg_dump -Fc -d appdb -f /var/lib/postgresql/appdb.dump
Punkt, który często umyka: pg_dump nie zabezpiecza ani ról, ani haseł. Te przechowywane są w obrębie całego klastra i trzeba je zapisać osobno, inaczej po odtworzeniu zabraknie dokładnie tych użytkowników, których potrzebuje aplikacja:
runuser -u postgres -- pg_dumpall --globals-only -f /var/lib/postgresql/globals.sql
Gdy wersje do siebie nie pasują
pg_dump: error: server version: 17.5; pg_dump version: 15.10
pg_dump: error: aborting because of server version mismatch
Zasada brzmi: pg_dump może być nowszy niż serwer, ale nigdy starszy. Na Debianie i Ubuntu łatwo to rozwiązać, bo /usr/bin/pg_dump to tylko wrapper, który dobiera odpowiednią wersję programu. Zainstaluj pakiet postgresql-client-18, a nowsza wersja będzie dostępna. Debianowym rozszerzeniem --cluster zmusisz z kolei wrapper do użycia konkretnego klastra, tutaj wersji 17, klaster main:
pg_dump --version
runuser -u postgres -- pg_dump --cluster 17/main -Fc -d appdb -f /var/lib/postgresql/appdb.dump
Trzymanie haseł poza skryptem
Przy automatycznych kopiach zapasowych hasło trafia do pliku .pgpass w formacie host:port:baza:uzytkownik:haslo. PostgreSQL bez słowa ignoruje ten plik, jeśli uprawnienia są zbyt szerokie. Równie ważne jest, w czyim katalogu domowym on leży, bo czytany jest zawsze plik użytkownika, na którym polecenie faktycznie działa. ~/.pgpass założony jako root pozostanie bez efektu, dopóki kopia zapasowa działa tak jak w tym artykule, przez runuser -u postgres. Wtedy liczy się katalog domowy użytkownika postgres:
touch /var/lib/postgresql/.pgpass
chown postgres:postgres /var/lib/postgresql/.pgpass
chmod 0600 /var/lib/postgresql/.pgpass
Pusty plik też pozostanie bez efektu. Wpisz po jednym wierszu na połączenie, na przykład 127.0.0.1:5432:appdb:appuser:TwojeSilneHaslo. Jeśli twoje zadanie kopii zapasowej działa zamiast tego bezpośrednio jako root, bez przełączania użytkownika, ten sam plik trafia do /root/.pgpass.
Sprawdzenie kopii zapasowej
Plik kopii zapasowej, który nigdy nie został odtworzony, jest tylko przypuszczeniem. Test zajmuje minutę. Najpierw zajrzyj do spisu treści, potem wczytaj kopię do bazy jednorazowej i policz tabele:
runuser -u postgres -- pg_restore -l /var/lib/postgresql/appdb.dump | head -n 20
runuser -u postgres -- createdb appdb_restore_test
runuser -u postgres -- pg_restore -d appdb_restore_test /var/lib/postgresql/appdb.dump
runuser -u postgres -- psql -d appdb_restore_test -c "\dt"
runuser -u postgres -- dropdb appdb_restore_test
Jeśli \dt pokazuje te same tabele co w oryginale, czyli tutaj przynajmniej tabelę probe, kopia zapasowa nadaje się do użytku. Jeśli natomiast polecenie zgłasza Did not find any relations., zabezpieczona baza była pusta i test niczego nie dowodzi. W bazie appdb sprzątasz potem tabelę testową poleceniem runuser -u postgres -- psql -d appdb -c "DROP TABLE probe;". Do codziennej pracy wystarczy wpis w /etc/cron.d, który odkłada oba pliki z datą w nazwie i usuwa starsze. Ważne, żeby pliki następnie opuszczały serwer. Kopia zapasowa na tym samym dysku pomaga przy przypadkowym DROP TABLE, ale nie przy awarii sprzętu.
Gdy klaster nie startuje
Jeśli usługa nie wstaje, status usługi mówi zwykle tylko tyle, że coś się nie powiodło. Właściwa przyczyna stoi w logu klastra:
tail -n 30 /var/log/postgresql/postgresql-*-main.log
Jeden wiersz możesz przy tym spokojnie pominąć. Znany z pierwszej sekcji komunikat FATAL: role "root" does not exist pochodzi zwykle od pg_isready: narzędzie buduje próbę połączenia na zalogowanym użytkowniku systemowym, czyli jako root, a serwer zapisuje w logu nieznaną rolę. Kod powrotu i tak pozostaje 0, wyjście brzmi accepting connections, a klaster jest w pełni sprawny.
Na systemach z systemd te same wiersze zwraca journalctl -u postgresql@17-main --no-pager -n 50. Zwróć uwagę na unit z numerem wersji: postgresql.service to tylko powłoka, która startuje wszystkie klastry, i zgłasza sukces także wtedy, gdy pojedynczy klaster się wywalił. Dlatego pewniejszą kontrolą jest pg_lsclusters.
Trzy komunikaty pokrywają większość przypadków. could not bind IPv4 address "0.0.0.0": Address already in use oznacza, że port zajmuje inny klaster, patrz sekcja o dwóch klastrach. Komunikat No space left on device przy zapisie postmaster.pid znaczy po prostu pełny dysk, co potwierdzisz poleceniem df -h. A błędy o nieprawidłowych uprawnieniach do katalogu danych pojawiają się po nieprzemyślanych przebiegach chmod albo chown: /var/lib/postgresql/17/main musi należeć do użytkownika postgres i mieć tryb 0700.
Na koniec jeszcze uwaga eksploatacyjna: PostgreSQL w ustawieniach domyślnych pracuje zachowawczo i ani trochę nie wykorzystuje całej pamięci RAM serwera. Zanim zaczniesz kręcić przy shared_buffers i work_mem, włącz pg_stat_statements z pakietu contrib i zobacz, które zapytania faktycznie kosztują czas. W praktyce wąskie gardło prawie zawsze leży w brakującym indeksie, a nie w parametrach pamięci.
Najczęstsze pytania
Którą wersję PostgreSQL dostanę w mojej dystrybucji?
Dlaczego przy uruchomieniu psql dostaję komunikat "role root does not exist"?
Co oznacza "no pg_hba.conf entry for host" i jak to naprawić?
Dlaczego mój użytkownik nie może tworzyć tabel, choć wolno mu korzystać z bazy?
Czy po zmianie w pg_hba.conf muszę restartować PostgreSQL?
Czy pg_dump wystarczy jako pełna kopia zapasowa?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

