Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

PostgreSQL nie czyta zmian z pliku konfiguracyjnego - który plik jest aktywny

W skrócie

  • Zmieniasz parametr w postgresql.conf, przeładowujesz konfigurację, a SHOW uparcie pokazuje starą wartość - jakby serwer w ogóle nie czytał tego pliku.
  • PostgreSQL czyta kilka plików w ustalonej kolejności, a ALTER SYSTEM nadpisuje je przez postgresql.auto.conf - edytujesz jeden plik, a wygrywa inny.
  • Pytamy serwer, który plik jest aktywny i skąd naprawdę pochodzi dana wartość, poprawiamy właściwe źródło i przeładowujemy albo restartujemy zależnie od parametru.

To jeden z najbardziej frustrujących momentów przy PostgreSQL: masz pewność, że zmieniłeś parametr, plik zapisany, reload wykonany - a baza zachowuje się, jakby nic się nie stało. W dziewięciu przypadkach na dziesięć powód jest ten sam: edytowałeś inny plik, niż serwer faktycznie czyta, albo Twoją wartość nadpisuje ustawienie z innego źródła. Na szczęście PostgreSQL potrafi sam wskazać, który plik jest aktywny i skąd dokładnie bierze każdą wartość.

Jak to wygląda w praktyce

Na Debianie albo Ubuntu poprawiasz /var/lib/postgresql/16/main/postgresql.conf, bo tam leżą dane - a serwer i tak czyta konfigurację z /etc/postgresql/16/main/, więc Twoja zmiana nie ma żadnego efektu. Inny wariant: dawno temu ktoś wykonał ALTER SYSTEM SET work_mem = ..., wartość wylądowała w postgresql.auto.conf, a ten plik jest czytany na końcu i wygrywa z postgresql.conf. Ręcznie zmieniasz postgresql.conf, robisz reload, a SHOW work_mem; pokazuje starą liczbę, bo auto.conf ją przykrywa. Jeszcze inaczej bywa z parametrami, które w ogóle nie reagują na reload - zmieniasz shared_buffers, przeładowujesz i dziwisz się, że nic, bo ten akurat wymaga restartu.

Dlaczego tak się dzieje

PostgreSQL składa konfigurację z kilku źródeł czytanych w określonej kolejności, gdzie późniejsze przykrywa wcześniejsze. Najpierw postgresql.conf (i pliki dołączane przez include), a na samym końcu postgresql.auto.conf - plik, którym steruje wyłącznie polecenie ALTER SYSTEM. Dlatego wpis dodany przez ALTER SYSTEM zawsze wygra z tym samym parametrem ustawionym ręcznie w postgresql.conf. Do tego dochodzi rozjazd lokalizacji: pakiety Debiana rozdzielają dane (w /var/lib) od konfiguracji (w /etc), więc "oczywisty" plik obok danych bywa nieużywany. Ostatnia warstwa to kontekst parametru - część z nich (sighup) wystarczy przeładować, ale takie jak shared_buffers czy max_connections mają kontekst postmaster i zmieniają się dopiero po restarcie. Zamiast zgadywać, w którym z tych miejsc siedzi problem, można zapytać serwer wprost.

Jak to rozwiązać krok po kroku

  1. Ustal, który plik konfiguracyjny jest realnie aktywny: SHOW config_file;. To pełna ścieżka pliku, który serwer faktycznie wczytał - to jego edytuj, a nie ten, który wydaje się właściwy.
  2. Sprawdź, skąd naprawdę pochodzi konkretna wartość: SELECT name, setting, source, sourcefile, sourceline FROM pg_settings WHERE name = 'work_mem';. Kolumna source powie, czy to configuration file, czy postgresql.auto.conf (widoczne jako override lub z odpowiednim sourcefile), a sourcefile i sourceline wskażą dokładny plik i linię.
  3. Jeśli wartość pochodzi z auto.conf, a chcesz sterować nią ręcznie, usuń tam wpis poleceniem ALTER SYSTEM RESET work_mem; (albo ALTER SYSTEM RESET ALL; dla wszystkich). Nie edytuj postgresql.auto.conf ręcznie.
  4. Wprowadź zmianę w tym źródle, które ma wygrać - albo ręcznie w aktywnym postgresql.conf, albo poleceniem ALTER SYSTEM SET, jeśli wolisz zarządzać parametrem przez SQL. Trzymaj się jednej metody dla danego parametru, żeby uniknąć nakładania.
  5. Sprawdź kontekst parametru, żeby wiedzieć, czy wystarczy reload: SELECT name, context FROM pg_settings WHERE name = 'shared_buffers';. Wartość sighup oznacza reload, postmaster - konieczny restart.
  6. Zastosuj zmianę odpowiednią metodą: przeładowanie przez SELECT pg_reload_conf(); dla parametrów sighup, a pełny systemctl restart postgresql dla tych z kontekstem postmaster.

Jak sprawdzić, że zadziałało

Po przeładowaniu lub restarcie wykonaj SHOW nazwa_parametru; - musi pokazać nową wartość. Jeśli chcesz mieć pewność, że wartość pochodzi z zamierzonego źródła, wróć do SELECT setting, source, sourcefile FROM pg_settings WHERE name = 'nazwa_parametru'; i potwierdź, że source oraz sourcefile wskazują ten plik, który edytowałeś. Gdy podejrzewasz, że reload nie zdążył się przeładować albo w pliku jest błąd składni, zajrzyj do logu serwera - PostgreSQL zapisuje tam informację o wczytaniu konfiguracji, a przy literówce w pliku wypisze ostrzeżenie i pominie wadliwą linię. Kolumna pending_restart w pg_settings (wartość t) to jasny sygnał, że zmieniłeś parametr wymagający restartu, którego jeszcze nie wykonałeś.

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

Jak dowiedzieć się, który plik konfiguracyjny serwer naprawdę czyta?
Wykonaj SHOW config_file; - zwróci pełną ścieżkę pliku, który serwer faktycznie wczytał. To szczególnie ważne na Debianie i Ubuntu, gdzie plik obok danych bywa nieużywany, a aktywny leży w /etc/postgresql.
Dlaczego moja zmiana w postgresql.conf jest ignorowana?
Najczęściej dlatego, że ten sam parametr jest ustawiony przez ALTER SYSTEM w pliku postgresql.auto.conf, który czytany jest na końcu i przykrywa postgresql.conf. Sprawdź źródło wartości zapytaniem SELECT setting, source, sourcefile FROM pg_settings WHERE name = 'parametr';.
Jak usunąć wartość ustawioną wcześniej przez ALTER SYSTEM?
Wykonaj ALTER SYSTEM RESET nazwa_parametru; aby skasować pojedynczy wpis z postgresql.auto.conf, albo ALTER SYSTEM RESET ALL; dla wszystkich. Nie edytuj pliku postgresql.auto.conf ręcznie - służy do tego wyłącznie polecenie ALTER SYSTEM.
Skąd wiadomo, czy parametr wymaga reloadu, czy restartu?
Sprawdź jego kontekst: SELECT name, context FROM pg_settings WHERE name = 'parametr';. Wartość sighup oznacza, że wystarczy przeładowanie przez pg_reload_conf(), a postmaster - że konieczny jest pełny restart klastra. Kolumna pending_restart równa t sygnalizuje zmianę czekającą na restart.

Komentarze (0)

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

Brak komentarzy...