Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
PostgreSQL na Red Hat, Rocky lub Alma nie startuje po instalacji - brak initdb
Ten problem dotyczy instalacji PostgreSQL 16 z oficjalnego repozytorium PGDG na Red Hat Enterprise Linux, Rocky Linux i AlmaLinux. Pakiet instaluje się bez błędów, a pierwsze uruchomienie usługi kończy się niepowodzeniem. Pokażemy, co sprawdza usługa przed startem, jak zainicjalizować klaster w katalogu domyślnym albo własnym i jak potwierdzić, że serwer pracuje na właściwym PGDATA.
Instalacja przebiega bez błędów:
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo dnf install -y postgresql16-server
sudo systemctl start postgresql-16Adres repozytorium dotyczy wersji 9 systemu. Na wersji 8 albo 10 zmień w nim EL-9 na EL-8 albo EL-10, a na wersji 8 przed instalacją serwera wyłącz wbudowany moduł: sudo dnf -qy module disable postgresql.
Polecenie systemctl start kończy się niepowodzeniem, a systemctl status postgresql-16 pokazuje stan failed. Powód zapisał w dzienniku systemd (sudo journalctl -u postgresql-16 -n 20 --no-pager) skrypt sprawdzający, uruchamiany przed serwerem:
"/var/lib/pgsql/16/data/" is missing or empty.
Use "/usr/pgsql-16/bin/postgresql-16-setup initdb" to initialize the database cluster.
See /usr/share/doc/postgresql16/README.rpm-dist for more information.Ten sam komunikat zobaczysz w drugim wariancie: klaster założony ręcznie przez initdb w innym katalogu, na przykład /data_pg, a usługa nadal szuka danych w lokalizacji domyślnej.
Zobacz też: Szkolenie Administracja, replikacja i tuning baz danych PostgreSQL
Na Ubuntu instalacja pakietu od razu tworzy i uruchamia klaster. Na systemach z rodziny Red Hat, zgodnie z zasadami tych dystrybucji, PostgreSQL nie jest ani inicjalizowany, ani włączany do autostartu automatycznie. Plik usługi /usr/lib/systemd/system/postgresql-16.service ustawia Environment=PGDATA=/var/lib/pgsql/16/data/ i przed startem serwera wykonuje ExecStartPre=/usr/pgsql-16/bin/postgresql-16-check-db-dir ${PGDATA}.
Ten skrypt sprawdza, czy w PGDATA, czyli katalogu danych klastra, jest plik PG_VERSION i katalog base. Jeśli ich nie ma, wypisuje komunikat z poprzedniej sekcji i kończy się kodem 1, więc systemd nie uruchamia serwera. Autorzy pakietu celowo nie wywołują initdb automatycznie. Komentarz w skrypcie wskazuje ryzyko nadpisania cennej bazy, na przykład na zdalnym wolumenie, który montuje się z opóźnieniem.
Ten sam skrypt zatrzyma start także wtedy, gdy w PGDATA leży klaster z poprzedniej wersji. Wypisuje wtedy An old version of the database format was found. i podpowiada aktualizację klastra zamiast ponownego initdb.
sudo ls -la /var/lib/pgsql/16/data/. Pusty albo nieistniejący katalog oznacza, że klaster nie został zainicjalizowany.sudo /usr/pgsql-16/bin/postgresql-16-setup initdb. Skrypt wypisze Initializing database ... OK, a przebieg initdb zapisze w /var/lib/pgsql/16/initdb.log. Wywołuje initdb z opcjami -A scram-sha-256 --auth-local=peer, więc lokalnie przez gniazdo zalogujesz się jako systemowy użytkownik postgres bez hasła, a połączenia TCP wymagają hasła. Dodatkowe opcje initdb przekażesz zmienną PGSETUP_INITDB_OPTIONS./usr/lib/systemd/system, bo aktualizacja pakietu go nadpisze (ostrzega o tym komentarz w pliku). Utwórz nadpisanie poleceniem sudo systemctl edit postgresql-16 (plik trafi do katalogu /etc/systemd/system/postgresql-16.service.d) i wpisz:[Service]
Environment=PGDATA=/data_pg/Ten sam komentarz przypomina, że zmiana PGDATA zwykle wymaga też dostosowania SELinux. Nadaj nowemu katalogowi etykietę katalogu danych PostgreSQL: sudo semanage fcontext -a -t postgresql_db_t "/data_pg(/.*)?", a jeśli katalog już istnieje, także sudo restorecon -R -v /data_pg.sudo /usr/pgsql-16/bin/postgresql-16-setup initdb. Skrypt odczytuje PGDATA z ustawień usługi (systemctl show -p Environment) i sam tworzy brakujący katalog z właścicielem postgres i prawami tylko dla niego, a potem wywołuje dla niego restorecon. Jeśli katalog już istnieje, na przykład jako punkt montowania, skrypt nie zmieni jego właściciela, więc najpierw wykonaj sudo chown postgres:postgres /data_pg i sudo chmod 700 /data_pg. Jeśli klaster już tam jest, bo założyłeś go ręcznie, skrypt odpowie Data directory is not empty! i niczego nie zmieni. Wtedy pomiń ten krok.sudo -u postgres /usr/pgsql-16/bin/pg_ctl -D /data_pg stop. Usługa i proces uruchomiony przez pg_ctl nie wiedzą o sobie, a drugi start na zajętym porcie się nie uda. Potem włącz autostart i uruchom usługę: sudo systemctl enable postgresql-16 oraz sudo systemctl start postgresql-16.Sprawdź trzy rzeczy:
sudo systemctl status postgresql-16
sudo systemctl show -p Environment postgresql-16
sudo -u postgres /usr/pgsql-16/bin/psql -c "SHOW data_directory;"Usługa powinna być w stanie active (running). Drugie polecenie pokazuje PGDATA, które systemd przekazuje serwerowi, a trzecie katalog, z którego serwer faktycznie pracuje. Obie ścieżki muszą wskazywać ten sam katalog, przy czym SHOW data_directory pokazuje ścieżkę bez końcowego ukośnika. Parametr data_directory ma kontekst postmaster, czyli ustala się go przy starcie serwera, więc wynik odpowiada bieżącemu uruchomieniu. Po restarcie maszyny usługa powinna wstać sama, bo ma włączony autostart.
Wróć do listy: 112 najczęstszych pytań i problemów z PostgreSQL
Komentarze (0)
Brak komentarzy...