Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Zimny backup i przenoszenie klastra na inny serwer

W skrócie

  • Skopiowałeś katalog danych działającego PostgreSQL na inny serwer i po starcie klaster nie wstaje albo dane są uszkodzone.
  • Zimny backup to fizyczna kopia katalogu danych, która musi być zrobiona przy całkowicie zatrzymanym serwerze, bo w locie kopiujemy pliki będące w trakcie zapisu.
  • Zatrzymaj serwer, skopiuj cały katalog danych razem z tablespace'ami, odtwórz go na nowej maszynie z tą samą wersją PostgreSQL i tą samą architekturą, popraw uprawnienia i wystartuj.

Zimny backup (offline, cold backup) to najprostsza metoda kopii zapasowej PostgreSQL: zatrzymujemy serwer i kopiujemy pliki. Brzmi banalnie, ale właśnie na tej banalności najłatwiej się przewrócić - kopiując katalog przy działającym serwerze albo przenosząc go na binaria w innej wersji. Pokażemy, jak zrobić to poprawnie i jak bezpiecznie przenieść cały klaster na inną maszynę.

Jak to wygląda w praktyce

Najczęstszy scenariusz: skopiowałeś katalog danych zwykłym cp -r na działającej bazie, przeniosłeś go na nowy serwer i przy starcie dostajesz błędy o niespójnym stanie WAL, komunikat o "database files are incompatible with server" albo baza wstaje, ale brakuje w niej ostatnich transakcji. Inny wariant: skopiowałeś dane, ale serwer nie chce wystartować, bo katalog należy do innego użytkownika niż lokalny postgres, albo tablespace'y wskazują na ścieżki, których na nowej maszynie nie ma. Zdarza się też, że przeniosłeś dane z PostgreSQL 15 na binaria PostgreSQL 16 i dostajesz odmowę startu, bo format katalogu danych zmienia się między wersjami głównymi.

Dlaczego tak się dzieje

PostgreSQL trzyma dane w plikach, które przy działającym serwerze są nieustannie modyfikowane, a część zmian siedzi jeszcze w buforach w pamięci i w plikach WAL, a nie w plikach tabel. Kopia zrobiona w locie łapie te pliki w różnych momentach, więc dostajesz niespójny obraz, którego serwer nie potrafi bezpiecznie odtworzyć. Dlatego zimny backup wymaga zatrzymanego serwera - dopiero wtedy wszystko jest zrzucone na dysk i spójne. Do tego format wewnętrzny katalogu danych jest przypisany do konkretnej wersji głównej i do architektury. Kopia jeden do jednego działa tylko między tą samą wersją główną (np. 16.x do 16.x) i tą samą architekturą oraz tą samą wielkością bloku. Między wersjami głównymi trzeba użyć pg_upgrade albo logicznego zrzutu, a nie zwykłej kopii plików.

Jak to rozwiązać krok po kroku

  1. Sprawdź wersję na obu maszynach: postgres --version (albo pg_config --version). Muszą się zgadzać co do wersji głównej i mieć tę samą architekturę.
  2. Zatrzymaj serwer na źródle w sposób kontrolowany: pg_ctl -D /ścieżka/do/data stop -m fast albo przez menedżer usług systemu. Upewnij się, że proces faktycznie zniknął.
  3. Zlokalizuj katalog danych (SHOW data_directory; przed zatrzymaniem) oraz wszystkie tablespace'y (zapytaj katalog pg_tablespace lub obejrzyj dowiązania w podkatalogu pg_tblspc). Musisz przenieść też dane tablespace'ów spoza głównego katalogu.
  4. Skopiuj cały katalog danych, zachowując uprawnienia i dowiązania, np. tar z zachowaniem atrybutów albo rsync -a. Skopiuj także katalogi tablespace'ów na te same ścieżki na nowej maszynie.
  5. Na nowej maszynie ustaw właściciela na użytkownika, pod którym działa PostgreSQL: chown -R postgres:postgres /ścieżka/do/data oraz uprawnienia katalogu danych na 0700 (albo 0750), inaczej serwer odmówi startu.
  6. Przejrzyj postgresql.conf i pg_hba.conf pod kątem ścieżek i adresów specyficznych dla starej maszyny. Jeśli tablespace'y muszą trafić w inne miejsce, popraw dowiązania w pg_tblspc.
  7. Wystartuj serwer i obserwuj log. Przy zimnym backupie z zatrzymanego serwera odtwarzanie WAL nie jest potrzebne, bo stan był już spójny.

Jak sprawdzić, że zadziałało

Po starcie zajrzyj do logu serwera - powinien pojawić się komunikat o gotowości do przyjmowania połączeń, bez ostrzeżeń o niespójności. Połącz się i sprawdź stan: SELECT pg_is_in_recovery(); powinno zwrócić false dla samodzielnego klastra. Policz kluczowe tabele i porównaj liczby z oryginałem, żeby mieć pewność, że dane są komplet. Sprawdź też, czy tablespace'y są widoczne i zdrowe: \db+ w psql pokaże listę wraz z lokalizacjami. Jeśli wszystko odpowiada źródłu, przeniesienie klastra się udało.

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

Czy zimny backup PostgreSQL można zrobić przy działającym serwerze?
Nie. Zimny backup wymaga całkowicie zatrzymanego serwera. Przy działającej bazie część zmian siedzi w buforach pamięci i w plikach WAL, a pliki tabel są w trakcie modyfikacji, więc kopia zrobiona w locie łapie niespójny obraz. Zatrzymaj serwer poleceniem pg_ctl stop albo przez menedżer usług, upewnij się, że proces zniknął, i dopiero wtedy kopiuj katalog danych. Jeśli potrzebujesz kopii bez przestoju, użyj kopii gorącej, na przykład pg_basebackup albo pgBackRest.
Czy skopiowany katalog danych zadziała na innej wersji PostgreSQL?
Nie między wersjami głównymi. Format wewnętrzny katalogu danych jest przypisany do konkretnej wersji głównej (na przykład 16.x) oraz do architektury i wielkości bloku. Kopia jeden do jednego działa tylko między tą samą wersją główną i tą samą architekturą. Przeniesienie z wersji 15 na 16 przez zwykłą kopię plików zakończy się odmową startu. Do zmiany wersji głównej użyj pg_upgrade albo migracji przez logiczny zrzut czy replikację logiczną.
Dlaczego po przeniesieniu katalogu danych serwer nie chce wystartować?
Najczęściej to kwestia właściciela i uprawnień katalogu danych. PostgreSQL odmawia startu, jeśli katalog nie należy do użytkownika, pod którym działa serwer, albo ma zbyt liberalne uprawnienia. Ustaw właściciela poleceniem chown na użytkownika postgres i nadaj katalogowi danych prawa 0700 lub 0750. Drugą częstą przyczyną są tablespace'y wskazujące na ścieżki, których na nowej maszynie nie ma, oraz ustawienia specyficzne dla starego hosta w plikach konfiguracyjnych.
Czy przenosząc klaster muszę kopiować tablespace'y osobno?
Tak, jeśli masz tablespace'y położone poza głównym katalogiem danych. W głównym katalogu leżą tylko dowiązania do nich w podkatalogu pg_tblspc, a same dane siedzą w innym miejscu na dysku. Zlokalizuj wszystkie tablespace'y (zapytaj katalog pg_tablespace przed zatrzymaniem serwera), skopiuj ich pliki na te same ścieżki na nowej maszynie i sprawdź, że dowiązania w pg_tblspc pokazują na właściwe lokalizacje. Pominięcie tablespace'a oznacza brak części danych po starcie.

Komentarze (0)

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

Brak komentarzy...