Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Klaster PostgreSQL nie uruchamia się - jak czytać komunikat pg_ctl

W skrócie

  • Problem: pg_ctl start kończy się krótkim komunikatem could not start server albo server did not start in time i nie wiadomo, co dalej.
  • Dlaczego: pg_ctl tylko uruchamia proces i czeka - faktyczny powód niepowodzenia trafia do logu serwera, a nie do wyniku komendy.
  • Rozwiązanie: uruchamiamy z jawnym katalogiem danych i plikiem logu, czytamy ostatnie linie logu i reagujemy na konkretny wpis FATAL.

pg_ctl to natywne narzędzie PostgreSQL do startu, zatrzymania i restartu klastra (grupy baz obsługiwanej przez jeden serwer). Gdy nie udaje mu się wstać, wypisuje bardzo lakoniczny komunikat - i tu wielu administratorów utyka. W tym wpisie pokazujemy, jak czytać to, co pg_ctl mówi, i skąd wziąć pełny powód. Dotyczy Cię to zwłaszcza wtedy, gdy zarządzasz bazą ręcznie, bez systemd, na przykład w kontenerze albo na starszym serwerze.

Jak to wygląda w praktyce

Klasyczny widok - komenda kończy się porażką, ale bez wyjaśnienia:

$ pg_ctl -D /var/lib/postgresql/16/main start
waiting for server to start....
pg_ctl: could not start server
Examine the log output.

Albo wariant z przekroczeniem czasu, gdy serwer wprawdzie startuje, ale wolno (np. odtwarza dane po awarii):

waiting for server to start.................... stopped waiting
pg_ctl: server did not start in time

Sam pg_ctl nie powie Ci więcej. Zdanie Examine the log output to nie ozdobnik - to dokładna instrukcja, gdzie szukać przyczyny.

Dlaczego tak się dzieje

pg_ctl jest cienką nakładką - jego zadaniem jest wystartować proces serwera postgres, poczekać określony czas i sprawdzić, czy klaster przyjmuje połączenia. Jeśli proces zakończy się błędem podczas inicjalizacji (na przykład uszkodzony plik konfiguracyjny, brak praw, zajęty port, niespójne pliki po twardym wyłączeniu maszyny), pg_ctl widzi tylko, że serwer nie wstał - konkretny komunikat FATAL trafia do logu. Przekroczenie czasu (did not start in time) jest inne - oznacza, że proces żyje, ale nie zdążył w domyślnym oknie czasu (parametr -t). Często tak wygląda odtwarzanie po niekontrolowanym wyłączeniu (crash recovery), gdy serwer przetwarza dziennik WAL, czyli log zmian zapisywanych przed samymi danymi.

Jak to rozwiązać krok po kroku

  1. Uruchom start z jawnym plikiem logu, żeby od razu mieć gdzie zajrzeć: pg_ctl -D /var/lib/postgresql/16/main -l /tmp/pg.log start.
  2. Zajrzyj do końca logu po powodzie: tail -n 30 /tmp/pg.log (lub do logu klastra w podkatalogu log/). Szukaj linii FATAL albo PANIC.
  3. Jeśli to przekroczenie czasu przy odtwarzaniu po awarii - daj serwerowi więcej czasu: pg_ctl -D /var/lib/postgresql/16/main -t 300 -w start i obserwuj log, gdzie widać postęp fazy redo.
  4. Jeśli log wskazuje na uszkodzoną konfigurację, sprawdź ją bez pełnego startu: postgres -D /var/lib/postgresql/16/main -C listen_addresses - błędny parametr zostanie wskazany.
  5. Jeśli widzisz komunikat o istniejącym pliku postmaster.pid po nagłym wyłączeniu, upewnij się, że żaden proces serwera nie działa (ps -ef | grep postgres), i dopiero wtedy usuń osierocony plik postmaster.pid z katalogu danych.
  6. Popraw znalezioną przyczynę i wystartuj ponownie tym samym poleceniem pg_ctl ... start.

Jak sprawdzić, że zadziałało

Po poprawnym starcie pg_ctl pokaże status uruchomionego serwera - sprawdź go wprost:

$ pg_ctl -D /var/lib/postgresql/16/main status
pg_ctl: server is running (PID: 12841)
/usr/lib/postgresql/16/bin/postgres "-D" "/var/lib/postgresql/16/main"

Potwierdź jeszcze, że klaster odpowiada na zapytania - pg_isready zwróci accepting connections, a psql -c "SELECT 1;" zwróci wynik.

Wróć do listy: 100 najczęstszych pytań i problemów z PostgreSQL

Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL

Sprawdź szkolenie: Administracja, replikacja i tuning baz danych PostgreSQL

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Szkolenie Zaawansowana administracja PostgreSQL - HA, DR, monitoring, skalowanie

Sprawdź szkolenie: Zaawansowana administracja PostgreSQL (HA, DR, monitoring, skalowanie)

To szkolenie może być dofinansowane z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Co dokładnie znaczy komunikat pg_ctl: could not start server?
Znaczy tyle, że proces serwera nie wstał, ale pg_ctl nie zna szczegółu. Sam pg_ctl jedynie uruchamia proces i czeka. Prawdziwy powód, na przykład zajęty port, złe uprawnienia albo błąd konfiguracji, jest zapisany w logu serwera. Dlatego komenda kończy się zdaniem Examine the log output, które trzeba potraktować dosłownie i zajrzeć do logu.
Dlaczego pg_ctl pokazuje server did not start in time, choć serwer w końcu wstaje?
To przekroczenie czasu oczekiwania - pg_ctl czeka domyślnie określoną liczbę sekund i jeśli klaster w tym czasie nie zacznie przyjmować połączeń, przerywa czekanie. Serwer może działać dalej w tle, na przykład odtwarzając dziennik WAL po awarii. Wydłuż okno przez pg_ctl -t 300 -w start i obserwuj postęp fazy redo w logu serwera.
Skąd pg_ctl wie, który klaster ma uruchomić?
Ze ścieżki katalogu danych podanej w parametrze -D albo ze zmiennej środowiskowej PGDATA. pg_ctl nie zakłada na siłę żadnej domyślnej lokalizacji, dlatego dobrze jest podawać -D jawnie. Ten sam pg_ctl obsłuży dowolny klaster na maszynie, o ile wskażesz mu właściwy katalog danych tego klastra.
Czy można ręcznie usunąć plik postmaster.pid, gdy serwer nie startuje?
Tak, ale tylko gdy masz pewność, że żaden proces serwera nie działa. Plik postmaster.pid w katalogu danych chroni przed uruchomieniem dwóch serwerów na tych samych plikach. Najpierw sprawdź ps -ef | grep postgres. Jeśli nic nie działa, a plik został po nagłym wyłączeniu, można go bezpiecznie usunąć i wystartować klaster ponownie.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...