Odtwarzanie kopii PostgreSQL to jedna z tych czynności, które z zewnątrz wyglądają banalnie, a w praktyce potrafią zatrzymać cały proces wdrożenia. Trzeba dobrać właściwe narzędzie, format archiwum, zakres danych i sposób nadpisania istniejącej bazy, żeby nie skończyć z częściowym restore albo niepotrzebnym przestojem. W temacie pg restore najczęściej chodzi o przywrócenie archiwum utworzonego przez pg_dump, z możliwością odtworzenia całej bazy albo tylko wybranych obiektów.
Najważniejsze rzeczy, które warto ustalić przed odtwarzaniem
-
pg_restoredziała na archiwach custom, directory i tar, a nie na zwykłym pliku SQL. - Jeśli backup jest plain SQL, zwykle używa się
psql, niepg_restore. - Do pełnego odtworzenia całej instancji PostgreSQL często potrzebujesz też
pg_dumpalldla ról i tablespaces. -
-Ctworzy bazę przed restore, a--cleanusuwa obiekty przed odtworzeniem. -
-jprzyspiesza duże restore, ale nie łączy się z--single-transaction. - Po restore zwykle warto uruchomić
ANALYZE, żeby planista dostał świeże statystyki.
Kiedy używam pg_restore, a kiedy sięgam po psql
Najpierw sprawdzam format pliku, bo od tego zależy całe działanie. pg_restore obsługuje archiwa custom, directory i tar, natomiast zwykły plik SQL odtwarza się przez psql. To brzmi jak drobiazg, ale w praktyce najwięcej nieporozumień bierze się właśnie z pomylenia tych dwóch ścieżek.
| Format kopii | Jak odtwarzać | Co zyskuję | Na co uważać |
|---|---|---|---|
Custom (-Fc) |
pg_restore |
Największa elastyczność i selektywne odtwarzanie obiektów | To nie jest plik do psql
|
Directory (-Fd) |
pg_restore |
Dobre do dużych baz i trybu równoległego | To katalog, nie pojedynczy plik |
Tar (-Ft) |
pg_restore |
Wygodne przenoszenie archiwum między systemami | Mniej wygodne niż directory przy bardzo dużych restore'ach |
| Plain SQL | psql |
Prosty skrypt do wykonania linia po linii |
pg_restore nie odtworzy takiego dumpa |
| Wszystkie bazy klastra |
pg_dumpall + psql
|
Również role, tablespaces i obiekty globalne | To już restore całej instancji, nie pojedynczej bazy |
Jeśli backup jest w formacie plain SQL, pg_restore nie pomoże. To częsty błąd i zwykle pierwszy znak, że dump powstał bez opcji archiwalnej. Gdy format już się zgadza, można przejść do samego odtwarzania.

Jak odtworzyć bazę krok po kroku
Ja zwykle zaczynam od dwóch decyzji: czy baza ma zostać utworzona od zera, oraz czy restore ma iść do istniejącej instancji. Dopiero potem wybieram komendę. Jeśli nie jestem pewien formatu, najpierw sprawdzam, jak dokładnie powstał backup.
- Sprawdź, czy archiwum jest custom, directory albo tar.
- Jeśli chcesz utworzyć bazę automatycznie, użyj
-C; jeśli nie, podaj docelową bazę w-d. - Przy dużych backupach rozważ tryb równoległy
-j. - Uruchom restore z
-v, żeby widzieć postęp i łatwiej wyłapać błędy. - Po zakończeniu sprawdź logi i wykonaj testy aplikacyjne.
pg_restore -C -d postgres -v backup.dump
pg_restore -d mydb -v backup.dump
pg_restore -d mydb -j 4 backup_dir/
W pierwszym wariancie -d postgres jest tylko bazą techniczną do połączenia, a właściwa baza jest tworzona z nazwy zapisanej w dumpie. W drugim przywracasz dane do już istniejącej bazy. Trzeci wariant wykorzystuję przy dużych restore'ach, gdy mam więcej niż jeden rdzeń CPU i nie chcę czekać godzinami.
Gdy sama ścieżka jest już jasna, warto przyjrzeć się opcjom, które realnie wpływają na czas i zakres odtwarzania.
Opcje, które naprawdę zmieniają przebieg restore'u
Nie wszystkie flagi są równie ważne. W praktyce najczęściej wracam do kilku, które decydują o tym, czy restore będzie szybki, bezpieczny i przewidywalny.
| Opcja | Co robi | Kiedy jej używam | Na co uważam |
|---|---|---|---|
-C |
Tworzy bazę przed odtworzeniem | Przy odtwarzaniu do świeżej bazy lub po pełnym odtworzeniu |
-d służy wtedy tylko jako baza do połączenia |
-c / --clean
|
Usuwa obiekty przed przywróceniem | Gdy nadpisuję istniejącą bazę | Dobrze łączyć z --if-exists, żeby ograniczyć komunikaty o brakujących obiektach |
-j |
Uruchamia restore równolegle | Przy dużych bazach i wielu rdzeniach | Nie działa z --single-transaction
|
-1 / --single-transaction
|
Odpala wszystko w jednej transakcji | Gdy zależy mi na podejściu all or nothing | Przy dużych bazach może zablokować dużo zasobów i nie łączy się z -j
|
-L |
Wczytuje edytowaną listę TOC | Gdy chcę pominąć albo przestawić wybrane obiekty | Najpierw robię listę przez -l
|
-t / -n
|
Odtwarza tylko tabelę albo schemat | Przy selektywnym restore | To nie zastępuje pełnego backupu, tylko zawęża zakres |
--section=data |
Odtwarza tylko dane, bez definicji obiektów | Gdy schema już istnieje | Przydatne przy etapowym odtwarzaniu |
--disable-triggers |
Czasowo wyłącza triggery podczas ładowania danych | Przy restore danych bez schema, gdy przeszkadzają ograniczenia | Wymaga superusera i używam tego tylko świadomie |
Najbardziej mylące połączenie to --single-transaction i -j. Pierwsze daje prostą ścieżkę wycofania, drugie przyspiesza duże bazy. W praktyce wybieram jedno z nich zależnie od ryzyka i rozmiaru danych. To prowadzi naturalnie do pytania, jak odzyskać tylko część bazy, a nie wszystko naraz.
Jak przywrócić tylko część bazy
pg_restore jest mocny właśnie wtedy, gdy nie trzeba odtwarzać wszystkiego. Mogę wskazać pojedynczą tabelę, cały schemat albo przeformatować kolejność obiektów z listą TOC. Przy większych migracjach to oszczędza naprawdę dużo czasu.
pg_restore -d mydb -t public.orders backup.dump
pg_restore -d mydb -n analytics backup.dump
pg_restore -l backup.dump > backup.list
pg_restore -L backup.list -d mydb backup.dump
pg_restore --section=pre-data -d mydb backup.dump
pg_restore --section=data -d mydb backup.dump
pg_restore --section=post-data -d mydb backup.dump
W praktyce korzystam z -t, gdy muszę odzyskać jedną tabelę albo kilka powiązanych obiektów. -n wybieram, gdy porządkuję cały schemat, a -L wtedy, gdy jeden problematyczny obiekt blokuje resztę restore'u i chcę świadomie przestawić kolejność. Przy dużych archiwach to bywa ważniejsze niż sama szybkość.
Przy częściach trzeba jednak uważać na duże obiekty i zależności. Large objects nie dają się filtrować tak precyzyjnie jak zwykłe tabele, więc jeśli archiwum je zawiera, zwykle dostajesz je wszystkie albo żadnego. To ważne zwłaszcza przy aplikacjach, które trzymają stare załączniki albo binarne dane w bazie. Następny problem to już nie zakres, tylko błędy, które potrafią zatrzymać odtwarzanie w połowie.
Najczęstsze błędy, które blokują restore
-
Zły format pliku. Jeśli próbuję odtworzyć plain SQL przez
pg_restore, proces po prostu nie ma prawa zadziałać. W takim przypadku przechodzę napsql. -
Brak ról lub obiektów globalnych. Sam restore jednej bazy nie odtworzy całej instancji PostgreSQL. Jeśli potrzebuję ról, tablespaces i uprawnień klastrowych, planuję osobny backup globalny przez
pg_dumpall. -
Kolizja
-jz--single-transaction. Te opcje rozwiązują dwa różne problemy i nie działają razem. Jeśli chcę paralelizacji, rezygnuję z jednej transakcji. -
--disable-triggersbez odpowiednich uprawnień. To opcja dla świadomego, administrowanego restore bez schema. Bez superusera zwykle kończy się błędem, więc nie traktuję jej jako domyślnego rozwiązania. -
Ograniczenia row security. Jeśli tabela ma RLS, restore może wymagać dodatkowych uprawnień. W takich sytuacjach pomocne bywa
--enable-row-security, ale działa ono tylko dla dumpów w formacieINSERT, nie dlaCOPY.
Najczęstszy błąd organizacyjny jest jeszcze prostszy: odtwarzanie na produkcji bez testu na kopii. Ja tego unikam, bo przy restore liczy się nie tylko to, że komenda się wykona, ale też to, czy baza zachowa się poprawnie po starcie aplikacji. Gdy restore przechodzi bez błędów, dopiero wtedy zaczyna się prawdziwa weryfikacja.
Co sprawdzam po odtworzeniu bazy, żeby nie wracać do niej jutro
Nie kończę pracy na komunikacie „completed successfully”. Po odtworzeniu zwykle robię trzy rzeczy: uruchamiam ANALYZE, sprawdzam kilka krytycznych zapytań aplikacji i potwierdzam, że liczba rekordów w najważniejszych tabelach wygląda sensownie. Jeśli robiłem restore po --clean, dodatkowo upewniam się, że uprawnienia i właściciele obiektów są zgodne z oczekiwaniami.
- Po dużym restore odpalam
ANALYZEalbo przynajmniej analizę kluczowych tabel. - Jeśli tymczasowo wyłączyłem archiwizację WAL albo zmieniłem ustawienia wydajności, przywracam je do normalnego stanu.
- Przy częściowym restore sprawdzam sekwencje, ograniczenia i zależności między tabelami.
- Przed produkcją testuję cały proces na kopii, bo to jedyny sposób, żeby zobaczyć błędy zanim pojawią się w krytycznym momencie.
Jeśli miałbym zostawić jedną praktyczną zasadę, byłaby prosta: najpierw dopasuj format dumpa do narzędzia, potem wybierz sposób restore, a dopiero na końcu optymalizuj czas. To właśnie wtedy odtwarzanie PostgreSQL staje się przewidywalnym procesem, a nie nerwowym ratowaniem sytuacji.
