PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Utwórz kopię zapasową PostgreSQL za pomocą pg_dump i pg_dumpall

Firmy i usługi dostarczają wartość w oparciu o dane. Dostępność, spójny stan i trwałość to najważniejsze priorytety dla zadowolenia klientów i użytkowników końcowych. Utracone lub niedostępne dane mogą być równoznaczne z utratą klientów.

Kopie zapasowe baz danych powinny znajdować się na czele codziennych operacji i zadań.

Powinniśmy być przygotowani na wypadek uszkodzenia lub utraty naszych danych.

Mocno wierzę w stare powiedzenie, które słyszałem:„Lepiej mieć to i nie potrzebować niż potrzebować i nie mieć . "

Dotyczy to również kopii zapasowych baz danych. Spójrzmy prawdzie w oczy, bez nich w zasadzie nic nie masz. Opieranie się na przekonaniu, że nic nie może się stać z Twoimi danymi, jest błędem.

Większość DBMS zapewnia wbudowane narzędzia do tworzenia kopii zapasowych. PostgreSQL ma pg_dump i pg_dumpall po wyjęciu z pudełka.

Oba oferują liczne opcje dostosowywania i strukturyzacji. Ujęcie ich wszystkich z osobna w jednym poście na blogu byłoby prawie niemożliwe. Zamiast tego przyjrzę się przykładom, które mogę najlepiej zastosować w moim osobistym środowisku rozwoju/nauki.

Biorąc to pod uwagę, ten wpis na blogu nie jest skierowany do środowiska produkcyjnego. Bardziej prawdopodobne, że jedna stacja robocza/środowisko programistyczne powinno przynieść największe korzyści.

Co to są pg_dump i pg_dumpall?

Dokumentacja opisuje pg_dump jako:„pg_dump to narzędzie do tworzenia kopii zapasowych bazy danych PostgreSQL”

I dokumentacja pg_dumpall:„pg_dumpall to narzędzie do zapisywania („zrzucania”) wszystkich baz danych PostgreSQL klastra w jednym pliku skryptu”.

Tworzenie kopii zapasowej bazy danych i/lub tabel

Na początek stworzę ćwiczebną bazę danych i kilka tabel do pracy za pomocą poniższego SQL:

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE
example_backups=# CREATE TABLE students(id INTEGER,
example_backups(# f_name VARCHAR(20),
example_backups(# l_name VARCHAR(20));
CREATE TABLE
example_backups=# CREATE TABLE classes(id INTEGER,
example_backups(# subject VARCHAR(20));
CREATE TABLE
example_backups=# INSERT INTO students(id, f_name, l_name)
example_backups-# VALUES (1, 'John', 'Thorn'), (2, 'Phil', 'Hampt'),
example_backups-# (3, 'Sue', 'Dean'), (4, 'Johnny', 'Rames');
INSERT 0 4
example_backups=# INSERT INTO classes(id, subject)
example_backups-# VALUES (1, 'Math'), (2, 'Science'),
example_backups-# (3, 'Biology');
INSERT 0 3
example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)
example_backups=# SELECT * FROM students;
id | f_name | l_name
----+--------+--------
 1 | John   | Thorn
 2 | Phil   | Hampt
 3 | Sue    | Dean
 4 | Johnny | Rames
(4 rows)
example_backups=# SELECT * FROM classes;
id | subject
----+---------
 1 | Math
 2 | Science
 3 | Biology
(3 rows)

Wszystkie bazy danych i tabele zostały skonfigurowane.

Uwaga:

W wielu z tych przykładów skorzystam z \! meta-polecenie, pozwalające albo wpaść do powłoki (linia poleceń), albo wykonać dowolne polecenia powłoki, które następują po niej.

Pamiętaj tylko, że w terminalu lub sesji wiersza poleceń (oznaczonych w tym poście na początku „$”), \! metapolecenie nie powinno być zawarte w żadnym z poleceń pg_dump lub pg_dumpall. Ponownie, jest to wygodne metapolecenie w psql.

Tworzenie kopii zapasowej pojedynczej tabeli

W tym pierwszym przykładzie zrzucę tylko tabelę uczniów:

example_backups=# \! pg_dump -U postgres -t students example_backups > ~/Example_Dumps/students.sql.

Wypisując zawartość katalogu, widzimy, że plik tam jest:

example_backups=# \! ls -a ~/Example_Dumps
.  .. students.sql

Opcje wiersza poleceń dla tego pojedynczego polecenia to:

  • -U postgres:określona nazwa użytkownika
  • -t studenci:stół do zrzucenia
  • przykładowe_kopie zapasowe:baza danych

Co znajduje się w pliku students.sql?

$ cat students.sql
--
-- PostgreSQL database dump
--
-- Dumped from database version 10.4 (Ubuntu 10.4-2.pgdg16.04+1)
-- Dumped by pg_dump version 10.4 (Ubuntu 10.4-2.pgdg16.04+1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
 
SET default_tablespace = '';
 
SET default_with_oids = false;
 
--
-- Name: students; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE public.students (
   id integer,
   f_name character varying(20),
   l_name character varying(20)
);
 
ALTER TABLE public.students OWNER TO postgres;
 
--
-- Data for Name: students; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY public.students (id, f_name, l_name) FROM stdin;
1 John Thorn
2 Phil Hampt
3 Sue Dean
4 Johnny Rames
\.
--
-- PostgreSQL database dump complete

Widzimy, że plik zawiera niezbędne polecenia SQL do ponownego utworzenia i ponownego wypełnienia uczniów tabeli.

Ale czy kopia zapasowa jest dobra? Niezawodny i działający?

Przetestujemy to i zobaczymy.

example_backups=# DROP TABLE students;
DROP TABLE
example_backups=# \dt;
         List of relations
Schema |  Name | Type  | Owner
--------+---------+-------+----------
public | classes | table | postgres
(1 row)

Zniknęło.

Następnie z wiersza poleceń przekaż zapisaną kopię zapasową do psql:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/students.sql
Password for user postgres:
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
COPY 4

Sprawdźmy w bazie danych:

example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)
example_backups=# SELECT * FROM students;
id | f_name | l_name
----+--------+--------
 1 | John   | Thorn
 2 | Phil   | Hampt
 3 | Sue    | Dean
 4 | Johnny | Rames
(4 rows)

Tabela i dane zostały przywrócone.

Tworzenie kopii zapasowych wielu tabel

W następnym przykładzie utworzymy kopię zapasową obu tabel za pomocą tego polecenia:

example_backups=# \! pg_dump -U postgres -W -t classes -t students -d example_backups > ~/Example_Dumps/all_tables.sql
Password:

(Zauważ, że musiałem podać hasło w tym poleceniu ze względu na opcję -W, której nie zrobiłem w pierwszym przykładzie. Więcej na ten temat wkrótce.)

Sprawdźmy ponownie, czy plik został utworzony, wypisując zawartość katalogu:

example_backups=# \! ls -a ~/Example_Dumps
.  .. all_tables.sql  students.sql

Następnie upuść tabele:

example_backups=# DROP TABLE classes;
DROP TABLE
example_backups=# DROP TABLE students;
DROP TABLE
example_backups=# \dt;
Did not find any relations.

Następnie przywróć plik kopii zapasowej all_tables.sql:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/all_tables.sql
Password for user postgres:
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 3
COPY 4
example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)

Obie tabele zostały przywrócone.

Jak widać z pg_dump, możesz wykonać kopię zapasową tylko jednej lub wielu tabel w określonej bazie danych.

Tworzenie kopii zapasowej bazy danych

Zobaczmy teraz, jak wykonać kopię zapasową całej bazy danych example_backups za pomocą pg_dump.

example_backups=# \! pg_dump -U postgres -W -d example_backups > ~/Example_Dumps/ex_back_db.sql
Password:
 
example_backups=# \! ls -a ~/Example_Dumps
.  .. all_tables.sql  ex_back_db.sql students.sql

Znajduje się tam plik ex_back_db.sql.

Połączę się z bazą danych postgres, aby usunąć bazę danych example_backups.

postgres=# DROP DATABASE example_backups;
DROP DATABASE

Następnie przywróć z wiersza poleceń:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/ex_back_db.sql
Password for user postgres:
psql: FATAL:  database "example_backups" does not exist

Nie ma go tam. Dlaczego nie? A gdzie to jest?

Najpierw musimy to stworzyć.

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE

Następnie przywróć za pomocą tego samego polecenia:

$ psql -U postgres -W -d example_backups -f ~/Example_Dumps/ex_back_db.sql
Password for user postgres:
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
CREATE EXTENSION
COMMENT
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 3
COPY 4
postgres=# \c example_backups;
You are now connected to database "example_backups" as user "postgres".
example_backups=# \dt;
         List of relations
Schema |   Name | Type  | Owner
--------+----------+-------+----------
public | classes  | table | postgres
public | students | table | postgres
(2 rows)

Baza danych i wszystkie tabele obecne i rozliczane.

Możemy uniknąć takiego scenariusza, w którym trzeba najpierw utworzyć docelową bazę danych, włączając opcję -C podczas tworzenia kopii zapasowej.

example_backups=# \! pg_dump -U postgres -W -C -d example_backups > ~/Example_Dumps/ex_back2_db.sql
Password:

Ponownie połączę się z bazą danych postgres i usunę bazę danych example_backups, abyśmy mogli zobaczyć, jak teraz działa przywracanie (zwróć uwagę, że polecenia connect i DROP nie są pokazane dla zwięzłości).

Następnie w wierszu poleceń (zwróć uwagę na brak opcji -d dbname):

$ psql -U postgres -W -f ~/Example_Dumps/ex_back2_db.sql
Password for user postgres:
……………..
(And partway through the output...)
CREATE DATABASE
ALTER DATABASE
Password for user postgres:
You are now connected to database "example_backups" as user "postgres".
SET
SET
SET
SET
SET
set_config
------------
(1 row)
 
SET
SET
SET
CREATE EXTENSION
COMMENT
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 3
COPY 4

Używając opcji -C, zostaniemy poproszeni o hasło, aby nawiązać połączenie, jak wspomniano w dokumentacji dotyczącej flagi -C:

„Rozpocznij wyniki od polecenia utworzenia samej bazy danych i ponownego połączenia z utworzoną bazą danych”.

Następnie w sesji psql:

postgres=# \c example_backups;
You are now connected to database "example_backups" as user "postgres".

Wszystko zostaje przywrócone, gotowe do pracy i bez konieczności tworzenia docelowej bazy danych przed przywróceniem.

pg_dumpall dla całego klastra

Do tej pory wykonaliśmy kopię zapasową pojedynczej tabeli, wielu tabel i pojedynczej bazy danych.

Ale jeśli chcemy czegoś więcej, na przykład tworzenia kopii zapasowej całego klastra PostgreSQL, musimy użyć pg_dumpall.

Jakie są więc godne uwagi różnice między pg_dump i pg_dumpall?

Na początek, oto ważne rozróżnienie w stosunku do dokumentacji:

„Ponieważ pg_dumpall odczytuje tabele ze wszystkich baz danych, najprawdopodobniej będziesz musiał połączyć się jako superużytkownik bazy danych, aby utworzyć kompletny zrzut. Ponadto będziesz potrzebować uprawnień superużytkownika, aby wykonać zapisany skrypt, aby móc dodawać użytkowników i grupy oraz tworzyć bazy danych”.

Używając poniższego polecenia, utworzę kopię zapasową całego klastra PostgreSQL i zapiszę go w pliku whole_cluster.sql:

$ pg_dumpall -U postgres -W -f ~/Example_Dumps/Cluster_Dumps/entire_cluster.sql
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:
Password:

Co u licha? Zastanawiasz się, czy muszę wpisywać hasło dla każdego monitu?

Tak, na pewno. 24 razy.

Policz je. (Hej, lubię odkrywać i zagłębiać się w różne bazy danych, gdy się uczę? Co mogę powiedzieć?)

Ale dlaczego wszystkie monity?

Przede wszystkim, czy po całej tej ciężkiej pracy pg_dumpall utworzył plik kopii zapasowej?

postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
.  .. entire_cluster.sql

Tak, plik kopii zapasowej tam jest.

Rzućmy trochę światła na całą tę „praktykę pisania ’ patrząc na ten fragment dokumentacji:

„pg_dumpall musi łączyć się kilka razy z serwerem PostgreSQL (raz na bazę danych). Jeśli korzystasz z uwierzytelniania hasłem, za każdym razem zostaniesz poproszony o podanie hasła”.

Wiem, o czym myślisz.

Może to nie być idealne lub nawet niewykonalne. A co z procesami, skryptami lub zadaniami cron, które działają w środku nocy?

Czy ktoś będzie unosił się nad klawiaturą, czekając na pisanie?

Prawdopodobnie nie.

Jednym ze skutecznych sposobów zapobiegania powtarzającym się monitom o hasło jest plik ~/.pgpass.

Oto składnia wymagana do działania pliku ~/.pgpass (przykład dostarczony z dokumentacji, patrz link powyżej):

hostname:port:database:username:password

Mając plik ~/.pgpass obecny w moim środowisku programistycznym, zawierający niezbędne dane uwierzytelniające dla roli postgres, mogę pominąć opcję -W (również -w) i uruchomić pg_dumpall bez ręcznego uwierzytelniania za pomocą hasła:

$ pg_dumpall -U postgres -f ~/Example_Dumps/Cluster_Dumps/entire_cluster2nd.sql

Lista zawartości katalogu:

postgres=# \! ls -a ~/Example_Dumps/Cluster_Dumps
.  .. entire_cluster2nd.sql  entire_cluster.sql

Plik jest tworzony i nie ma powtarzających się monitów o hasło.

Zapisany plik można ponownie załadować za pomocą psql podobnego do pg_dump.

Baza danych połączeń jest również mniej krytyczna, zgodnie z tym fragmentem z dokumentacji:„Nie jest ważne, z którą bazą danych się tutaj łączysz, ponieważ plik skryptu utworzony przez pg_dumpall będzie zawierał odpowiednie polecenia do tworzenia i łączenia się z zapisanymi bazami danych.”

Pobierz oficjalny dokument już dziś Zarządzanie i automatyzacja PostgreSQL za pomocą ClusterControlDowiedz się, co musisz wiedzieć, aby wdrażać, monitorować, zarządzać i skalować PostgreSQLPobierz oficjalny dokument

pg_dump, pg_dumpall i skrypty powłoki — przydatna kombinacja

W tej sekcji zobaczymy kilka przykładów włączenia pg_dump i pg_dumpall do prostych skryptów powłoki.

Wyjaśnij, że nie jest to samouczek dotyczący skryptu powłoki. Nie jestem też guru skryptów powłoki. Podam głównie kilka przykładów, których używam w moim lokalnym środowisku rozwoju/nauki.

Najpierw spójrzmy na prosty skrypt powłoki, którego można użyć do utworzenia kopii zapasowej pojedynczej bazy danych:

#!/bin/bash
# This script performs a pg_dump, saving the file the specified dir.
# The first arg ($1) is the database user to connect with.
# The second arg ($2) is the database to backup and is included in the file name.
# $(date +"%Y_%m_%d") includes the current system date into the actual file name.

pg_dump -U $1 -W -C -d $2 > ~/PG_dumps/Dump_Scripts/$(date +"%Y_%m_%d")_$2.sql

Jak widać, ten skrypt akceptuje 2 argumenty:pierwszy to użytkownik (lub rola), z którym należy się połączyć w celu wykonania kopii zapasowej, a drugi to nazwa bazy danych, której kopię zapasową chcesz utworzyć.

Zwróć uwagę na opcję -C w poleceniu, abyśmy mogli przywrócić, jeśli baza danych nie istnieje, bez konieczności wcześniejszego jej ręcznego tworzenia.

Wywołajmy skrypt z rolą postgres dla bazy danych example_backups (nie zapomnij, aby skrypt był wykonywalny z co najmniej chmod +x przed pierwszym wywołaniem):

$ ~/My_Scripts/pgd.sh postgres example_backups
Password:

I sprawdź, czy tam jest:

$ ls -a ~/PG_dumps/Dump_Scripts/
.  .. 2018_06_06_example_backups.sql

Przywracanie jest wykonywane za pomocą tego skryptu kopii zapasowej, jak w poprzednich przykładach.

Podobny skrypt powłoki może być użyty z pg_dumpall do tworzenia kopii zapasowej całego klastra PostgreSQL.

Ten skrypt powłoki prześle (|) pg_dumpall do gzip, który następnie zostanie skierowany do wskazanej lokalizacji pliku:

#!/bin/bash
# This shell script calls pg_dumpall and pipes into the gzip utility, then directs to
# a directory for storage.
# $(date +"%Y_%m_%d") incorporates the current system date into the file name.
 
pg_dumpall -U postgres | gzip > ~/PG_dumps/Cluster_Dumps/$(date +"%Y_%m_%d")_pg_bck.gz

W przeciwieństwie do poprzedniego przykładowego skryptu, ten nie akceptuje żadnych argumentów.

Wywołam ten skrypt w wierszu poleceń (bez pytania o hasło, ponieważ rola postgres używa pliku ~/.pgpass - patrz sekcja powyżej).

$ ~/My_Scripts/pgalldmp.sh

Po zakończeniu wymienię zawartość katalogu, pokazując również rozmiary plików w celu porównania plików .sql i gz:

postgres=# \! ls -sh ~/PG_dumps/Cluster_Dumps
total 957M
37M 2018_05_22_pg_bck.gz   32M 2018_06_06_pg_bck.gz 445M entire_cluster2nd.sql  445M entire_cluster.sql

Uwaga dotycząca formatu archiwum gz z dokumentacji:

„Alternatywne formaty plików archiwów muszą być użyte z pg_restore, aby odbudować bazę danych”.

Podsumowanie

Zebrałem kluczowe punkty z dokumentacji na temat pg_dump i pg_dumpall, wraz z moimi obserwacjami, aby zamknąć ten wpis na blogu:

Uwaga:punkty podane w dokumentacji są w cudzysłowie.

  • „pg_dump zrzuca tylko jedną bazę danych”
  • Domyślnym wyjściem dla pg_dump jest zwykły tekstowy format pliku SQL.
  • Rola wymaga uprawnienia SELECT do uruchomienia pg_dump zgodnie z następującym wierszem w dokumentacji:„pg_dump wewnętrznie wykonuje instrukcje SELECT. Jeśli masz problemy z uruchomieniem pg_dump, upewnij się, że jesteś w stanie wybrać informacje z bazy danych za pomocą, na przykład, psql”
  • Aby uwzględnić niezbędne polecenie DDL CREATE DATABASE i połączenie w pliku kopii zapasowej, dołącz opcję -C.
  • -W:Ta opcja zmusza pg_dump do pytania o hasło. Ta flaga nie jest konieczna, ponieważ jeśli serwer wymaga hasła, i tak zostaniesz o to poproszony. Niemniej jednak ten fragment w dokumentacji przykuł moją uwagę, więc pomyślałem, aby umieścić go tutaj:„Jednak pg_dump zmarnuje próbę połączenia, aby dowiedzieć się, że serwer chce hasła. W niektórych przypadkach warto wpisać -W, aby uniknąć dodatkowej próby połączenia.”
  • -d:Określa bazę danych, z którą chcesz się połączyć. Również w dokumentacji:„Jest to równoważne określeniu dbname jako pierwszego argumentu nie będącego opcją w wierszu poleceń”.
  • Wykorzystywanie flag, takich jak -t (tabela), pozwala użytkownikom na tworzenie kopii zapasowych części bazy danych, a mianowicie tabel, do których mają uprawnienia dostępu.
  • Formaty plików kopii zapasowych mogą się różnić. Jednak pliki .sql to świetny wybór między innymi. Pliki kopii zapasowej są ponownie odczytywane przez psql w celu przywrócenia.
  • pg_dump może wykonać kopię zapasową działającej, aktywnej bazy danych bez zakłócania innych operacji (tj. innych czytelników i pisarzy).
  • Jedno zastrzeżenie:pg_dump nie zrzuca ról ani innych obiektów bazy danych, w tym obszarów tabel, tylko pojedynczą bazę danych.
  • Aby wykonać kopie zapasowe całego klastra PostgreSQL, lepszym wyborem jest pg_dumpall.
  • pg_dumpall może obsłużyć cały klaster, tworząc kopie zapasowe informacji o rolach, obszarach tabel, użytkownikach, uprawnieniach itp., podczas gdy pg_dump nie może.
  • Szanse są, że rola z uprawnieniami SUPERUSER będzie musiała wykonać zrzut i odtworzyć/odtworzyć plik, gdy zostanie ponownie odczytany przez psql, ponieważ podczas przywracania wymagane jest uprawnienie do odczytu wszystkich tabel we wszystkich bazach danych.

Mam nadzieję, że w tym poście na blogu podałem odpowiednie przykłady i szczegóły dotyczące przeglądu na poziomie początkującym na temat pg_dump i pg_dumpall dla pojedynczych środowisk programistycznych/uczących się PostgreSQL.

Chociaż nie zbadano wszystkich dostępnych opcji, oficjalna dokumentacja zawiera mnóstwo informacji z przykładami dla obu narzędzi, więc upewnij się, że skorzystaj z tego źródła w celu dalszych badań, pytań i przeczytania.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Analiza porównawcza zarządzanych rozwiązań PostgreSQL w chmurze:część druga — Amazon RDS

  2. Laravel:Błąd [PDOException]:Nie można znaleźć sterownika w PostgreSQL

  3. Zapytanie o granty dla tabeli w postgres

  4. Zapytanie o elementy tablicy wewnątrz typu JSON

  5. Wiosna 2011 Konferencje PostgreSQL, USA/Kanada