Blog JSystems - uwalniamy wiedzę!

Szukaj

PostgreSQL

Odtwarzanie z pg_dump się wywala - kolejność i zależności

W skrócie

  • Odtwarzanie z pg_dump sypie błędami o brakujących rolach, nieistniejących obiektach albo naruszonych kluczach obcych i nie kończy się poprawnie.
  • Najczęściej to nie zepsuty backup, tylko problem kolejności: role muszą istnieć przed nadaniem uprawnień, a rozszerzenia i schematy - przed obiektami, które z nich korzystają.
  • Rozwiązujemy to, odtwarzając globalne role najpierw, używając formatu custom z pg_restore (który sam układa zależności) oraz opcji takich jak --clean, --if-exists i -j.

Nieudane odtwarzanie backupu to jeden z najbardziej nerwowych momentów w pracy administratora - zwłaszcza gdy dzieje się w trakcie awarii. Uspokajamy: w ogromnej większości przypadków winna jest kolejność i zależności, a nie uszkodzony dump. Pokażemy Ci, jak to rozplątać.

Jak to wygląda w praktyce

Uruchamiasz odtwarzanie i konsola zapełnia się błędami: "role X does not exist" przy GRANT, "schema Y does not exist", "relation Z does not exist" albo naruszenie klucza obcego przy wgrywaniu danych. Przy dumpie tekstowym (psql -f) skrypt leci dalej mimo błędów, więc na końcu masz bazę wgraną częściowo i nie wiesz, co się udało. Przy formacie custom pg_restore potrafi przerwać na pierwszym twardym błędzie. W obu wypadkach efekt jest ten sam: baza nie jest kompletna, a Ty musisz ustalić, czego brakowało w odpowiedniej kolejności.

Dlaczego tak się dzieje

Obiekty w bazie mają zależności. Nadanie uprawnienia (GRANT) wymaga, by rola już istniała - a role są globalne i pg_dump ich nie zawiera, więc jeśli nie wgrałeś ich wcześniej z pg_dumpall --globals-only, każdy GRANT się wywali. Widok zależy od tabeli, tabela z kluczem obcym zależy od tabeli nadrzędnej, funkcja może zależeć od typu, a wszystko - od schematu i ewentualnego rozszerzenia. Format tekstowy dumpa ma ustaloną kolejność poleceń, ale wykonywany przez psql nie zatrzymuje się na błędach (chyba że ustawisz ON_ERROR_STOP), więc pojedyncza wywrotka na początku kaskaduje dalej. Format custom jest tu wygodniejszy, bo pg_restore zna graf zależności i potrafi ułożyć odtwarzanie poprawnie.

Jak to rozwiązać krok po kroku

  1. Zacznij od ról. Zanim odtworzysz bazę, wgraj globalne obiekty: psql -f globalne.sql (plik z pg_dumpall --globals-only). To eliminuje gros błędów "role does not exist".
  2. Preferuj format custom. Jeśli masz dump -Fc, użyj pg_restore -d nazwa_bazy plik.dump - narzędzie samo poukłada kolejność obiektów zgodnie z zależnościami.
  3. Włącz zatrzymanie na błędzie, żeby nie kaskadowały. Dla psql: psql -v ON_ERROR_STOP=1 -f dump.sql. Dla pg_restore dodaj -e (exit on error), gdy chcesz twardo przerwać na pierwszym problemie.
  4. Przy odtwarzaniu na istniejącą bazę użyj --clean --if-exists w pg_restore - najpierw czyści stare obiekty (bezpiecznie, bez błędów o ich braku), potem tworzy nowe. Unikasz konfliktów "already exists".
  5. Dla problemów z kluczami obcymi przy dużych danych rozważ odtworzenie w kolejności: najpierw sam schemat i dane (--data-only wgrywane po strukturze), a więzy i indeksy z pg_restore, które i tak zakłada je po danych. W praktyce format custom robi to automatycznie.
  6. Przyspiesz i zrównoleglaj bezpiecznie: pg_restore -j 4 rozłoży pracę na cztery wątki, zachowując zależności. Działa tylko z formatem custom lub directory.
  7. Jeśli błędy dotyczą rozszerzeń ("extension does not exist"), upewnij się, że na docelowym serwerze są zainstalowane te same rozszerzenia (pakiety systemowe), zanim odtworzysz obiekty, które z nich korzystają.

Jak sprawdzić, że zadziałało

Najpewniejszy dowód to odtwarzanie zakończone bez błędów krytycznych - przejrzyj cały log, nie tylko koniec. Po odtworzeniu policz obiekty i porównaj z serwerem źródłowym: liczbę tabel, widoków, funkcji i rekordów w kilku kluczowych tabelach (SELECT count(*) FROM ...). Sprawdź, czy więzy integralności są aktywne i czy uprawnienia się zgadzają (\dp w psql). Jeśli używałeś pg_restore, możesz najpierw podejrzeć plan odtwarzania bez wykonywania go: pg_restore -l plik.dump wypisze listę obiektów w kolejności - to świetne narzędzie do diagnozy, gdy coś dalej nie wchodzi.

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

Dlaczego odtwarzanie zgłasza błąd, że rola nie istnieje?
Bo role są globalne dla klastra i pg_dump ich nie zawiera. Jeśli nie wgrałeś ich wcześniej z pg_dumpall --globals-only, każde polecenie GRANT w dumpie bazy odwołuje się do roli, której nie ma, i się wywala. Rozwiązanie to odtworzyć role najpierw, a dopiero potem samą bazę.
Jak zatrzymać odtwarzanie na pierwszym błędzie zamiast lecieć dalej?
Przy dumpie tekstowym uruchom psql z parametrem ON_ERROR_STOP ustawionym na 1, czyli psql -v ON_ERROR_STOP=1 -f dump.sql. Domyślnie psql leci dalej mimo błędów, przez co pojedyncza wywrotka kaskaduje w wiele kolejnych. Dla pg_restore analogiczne zachowanie daje przełącznik -e, który przerywa na pierwszym błędzie.
Jak uniknąć konfliktów typu obiekt już istnieje przy odtwarzaniu na istniejącą bazę?
W pg_restore użyj opcji --clean razem z --if-exists. Pierwsza usuwa istniejące obiekty przed odtworzeniem nowych, a druga sprawia, że usuwanie nieistniejących obiektów nie zgłasza błędu. Dzięki temu odtwarzanie na bazę, która już coś zawiera, przebiega czysto, bez konfliktów already exists ani błędów o braku obiektu.
Czy format custom sam radzi sobie z kolejnością zależności?
Tak, i to jego duża zaleta. pg_restore zna graf zależności obiektów zapisany w dumpie custom i układa odtwarzanie w poprawnej kolejności: schematy i rozszerzenia przed obiektami, tabele nadrzędne przed kluczami obcymi, dane przed założeniem części więzów. Dlatego przy problemach z kolejnością warto backupować w formacie -Fc zamiast tekstowym.

Komentarze (0)

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

Brak komentarzy...