PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Sichern Sie PostgreSQL mit pg_dump und pg_dumpall

Unternehmen und Dienstleistungen liefern Wert basierend auf Daten. Verfügbarkeit, konsistenter Zustand und Langlebigkeit sind oberste Prioritäten, um Kunden und Endbenutzer zufrieden zu stellen. Verlorene oder unzugängliche Daten können möglicherweise verlorenen Kunden gleichkommen.

Datenbanksicherungen sollten bei den täglichen Vorgängen und Aufgaben im Vordergrund stehen.

Wir sollten auf den Fall vorbereitet sein, dass unsere Daten beschädigt werden oder verloren gehen.

Ich glaube fest an ein altes Sprichwort, das ich gehört habe:„Es ist besser, es zu haben und es nicht zu brauchen, als es zu brauchen und es nicht zu haben . "

Das gilt auch für Datenbanksicherungen. Seien wir ehrlich, ohne sie haben Sie im Grunde nichts. Die Annahme, dass Ihren Daten nichts passieren kann, ist ein Trugschluss.

Die meisten DBMS bieten einige Mittel für integrierte Backup-Utilities. PostgreSQL hat pg_dump und pg_dumpall von Haus aus.

Beide bieten zahlreiche Anpassungs- und Strukturierungsmöglichkeiten. Sie alle einzeln in einem Blogbeitrag zu behandeln, wäre nahezu unmöglich. Stattdessen schaue ich mir die Beispiele an, die ich am besten auf meine persönliche Entwicklung/Lernumgebung anwenden kann.

Allerdings richtet sich dieser Blogbeitrag nicht an eine Produktionsumgebung. Wahrscheinlich sollte eine einzelne Workstation/Entwicklungsumgebung am meisten davon profitieren.

Was sind pg_dump und pg_dumpall?

Die Dokumentation beschreibt pg_dump als:„pg_dump ist ein Dienstprogramm zum Sichern einer PostgreSQL-Datenbank“

Und die pg_dumpall-Dokumentation:„pg_dumpall ist ein Dienstprogramm zum Ausgeben („Dumpen“) aller PostgreSQL-Datenbanken eines Clusters in eine Skriptdatei.“

Sichern einer Datenbank und/oder Tabelle(n)

Zu Beginn erstelle ich eine Übungsdatenbank und einige Tabellen, mit denen ich arbeiten kann, indem ich das folgende SQL verwende:

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)

Datenbank und Tabellen sind alle eingerichtet.

Hinweis:

In vielen dieser Beispiele nutze ich psql's \! meta-Befehl, mit dem Sie entweder in eine Shell (Befehlszeile) wechseln oder die folgenden Shell-Befehle ausführen können.

Beachten Sie jedoch, dass in einer Terminal- oder Befehlszeilensitzung (in diesem Blogbeitrag durch ein führendes „$“ gekennzeichnet) das \! meta-command sollte nicht in einem der pg_dump- oder pg_dumpall-Befehle enthalten sein. Auch hier handelt es sich um einen praktischen Metabefehl innerhalb von psql.

Eine einzelne Tabelle sichern

In diesem ersten Beispiel werde ich nur die Tabelle students ausgeben:

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

Wenn wir den Inhalt des Verzeichnisses auflisten, sehen wir, dass die Datei dort ist:

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

Die Befehlszeilenoptionen für diesen einzelnen Befehl sind:

  • -U postgres:der angegebene Benutzername
  • -t students:die Tabelle zum Sichern
  • example_backups:die Datenbank

Was enthält die Datei 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

Wir können sehen, dass die Datei die notwendigen SQL-Befehle enthält, um die Tabelle students neu zu erstellen und neu zu füllen.

Aber ist die Sicherung gut? Zuverlässig und funktionsfähig?

Wir werden es testen und sehen.

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

Es ist weg.

Übergeben Sie dann von der Befehlszeile aus die gespeicherte Sicherung an 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

Lassen Sie uns in der Datenbank überprüfen:

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)

Tabelle und Daten wurden wiederhergestellt.

Mehrere Tabellen sichern

In diesem nächsten Beispiel sichern wir beide Tabellen mit diesem Befehl:

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

(Beachten Sie, dass ich in diesem Befehl aufgrund der Option -W ein Passwort angeben musste, was ich im ersten Beispiel nicht getan habe. Mehr dazu folgt.)

Lassen Sie uns noch einmal überprüfen, ob die Datei erstellt wurde, indem wir den Inhalt des Verzeichnisses auflisten:

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

Dann löschen Sie die Tabellen:

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

Stellen Sie dann mit der Sicherungsdatei all_tables.sql wieder her:

$ 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)

Beide Tabellen wurden wiederhergestellt.

Wie wir mit pg_dump sehen können, können Sie nur eine oder mehrere Tabellen innerhalb einer bestimmten Datenbank sichern.

Datenbank sichern

Sehen wir uns nun an, wie die gesamte Datenbank example_backups mit pg_dump gesichert wird.

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

Dort befindet sich die Datei ex_back_db.sql.

Ich verbinde mich mit der Postgres-Datenbank, um die example_backups-Datenbank zu löschen.

postgres=# DROP DATABASE example_backups;
DROP DATABASE

Stellen Sie dann über die Befehlszeile wieder her:

$ 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

Es ist nicht da. Warum nicht? Und wo ist es?

Wir müssen es zuerst erstellen.

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE

Stellen Sie dann mit demselben Befehl wieder her:

$ 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)

Datenbank und alle Tabellen vorhanden und berücksichtigt.

Wir können dieses Szenario vermeiden, in dem wir zuerst die Zieldatenbank erstellen müssen, indem wir beim Erstellen der Sicherung die Option -C angeben.

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

Ich werde mich wieder mit der Postgres-Datenbank verbinden und die example_backups-Datenbank löschen, damit wir sehen können, wie die Wiederherstellung jetzt funktioniert (beachten Sie, dass die Connect- und DROP-Befehle der Kürze halber nicht gezeigt werden).

Dann auf der Befehlszeile (beachten Sie, dass die Option -d dbname nicht enthalten ist):

$ 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

Mit der Option -C werden wir nach einem Passwort gefragt, um eine Verbindung herzustellen, wie in der Dokumentation zum Flag -C erwähnt:

„Beginnen Sie die Ausgabe mit einem Befehl, um die Datenbank selbst zu erstellen und sich erneut mit der erstellten Datenbank zu verbinden.“

Dann in der psql-Sitzung:

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

Alles ist wiederhergestellt, einsatzbereit und ohne dass die Zieldatenbank vor der Wiederherstellung erstellt werden muss.

pg_dumpall für den gesamten Cluster

Bisher haben wir eine einzelne Tabelle, mehrere Tabellen und eine einzelne Datenbank gesichert.

Aber wenn wir mehr als das wollen, zum Beispiel den gesamten PostgreSQL-Cluster sichern, müssen wir dort pg_dumpall verwenden.

Was sind also einige bemerkenswerte Unterschiede zwischen pg_dump und pg_dumpall?

Für den Anfang ist hier ein wichtiger Unterschied zur Dokumentation:

„Da pg_dumpall Tabellen aus allen Datenbanken liest, müssen Sie sich höchstwahrscheinlich als Datenbank-Superuser anmelden, um einen vollständigen Dump zu erstellen. Außerdem benötigen Sie Superuser-Rechte, um das gespeicherte Skript auszuführen, damit Sie Benutzer und Gruppen hinzufügen und Datenbanken erstellen können.“

Mit dem folgenden Befehl sichere ich meinen gesamten PostgreSQL-Cluster und speichere ihn in der Datei 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:

Was in aller Welt? Fragen Sie sich, ob ich für jede Eingabeaufforderung ein Passwort eingeben musste?

Ja, sicher. 24 Mal.

Zähl sie. (Hey, ich erkunde und vertiefe mich gerne in verschiedene Datenbanken, während ich lerne? Was soll ich sagen?)

Aber warum all die Eingabeaufforderungen?

Hat pg_dumpall nach all der harten Arbeit die Sicherungsdatei erstellt?

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

Ja, die Sicherungsdatei ist da.

Lassen Sie uns etwas Licht auf all diese "Schreibübungen werfen ’, indem Sie sich diese Passage aus der Dokumentation ansehen:

„pg_dumpall muss sich mehrmals mit dem PostgreSQL-Server verbinden (einmal pro Datenbank). Wenn Sie die Passwortauthentifizierung verwenden, wird jedes Mal nach einem Passwort gefragt.“

Ich weiß, was du denkst.

Dies ist möglicherweise nicht ideal oder sogar machbar. Was ist mit Prozessen, Skripten oder Cron-Jobs, die mitten in der Nacht ausgeführt werden?

Wird jemand über die Tastatur schweben und auf die Eingabe warten?

Wahrscheinlich nicht.

Eine wirksame Maßnahme, um zu verhindern, dass diese wiederholten Passwortabfragen angezeigt werden, ist eine ~/.pgpass-Datei.

Hier ist die Syntax, die die ~/.pgpass-Datei benötigt, um zu funktionieren (Beispiel aus der Dokumentation, siehe Link oben):

hostname:port:database:username:password

Mit einer ~/.pgpass-Datei, die in meiner Entwicklungsumgebung vorhanden ist und die erforderlichen Anmeldeinformationen für die Postgres-Rolle enthält, kann ich die Option -W (auch -w) weglassen und pg_dumpall ausführen, ohne mich manuell mit dem Passwort zu authentifizieren:

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

Verzeichnisinhalt auflisten:

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

Die Datei wird erstellt und keine wiederholten Passwortabfragen.

Die gespeicherte Datei kann mit psql ähnlich wie pg_dump neu geladen werden.

Auch die Verbindungsdatenbank ist laut dieser Passage aus der Dokumentation weniger kritisch:„Es ist nicht wichtig, zu welcher Datenbank Sie sich hier verbinden, da die von pg_dumpall erstellte Skriptdatei die entsprechenden Befehle zum Erstellen und Verbinden mit den gespeicherten Datenbanken enthält.“

Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunter

pg_dump, pg_dumpall und Shell-Skripte - eine praktische Kombination

In diesem Abschnitt sehen wir einige Beispiele für die Einbindung von pg_dump und pg_dumpall in einfache Shell-Skripte.

Seien Sie sich klar, dies ist kein Shell-Skript-Tutorial. Ich bin auch kein Shell-Script-Guru. Ich werde hauptsächlich ein paar Beispiele geben, die ich in meiner lokalen Entwicklungs-/Lernumgebung verwende.

Schauen wir uns zunächst ein einfaches Shell-Skript an, mit dem Sie eine einzelne Datenbank sichern können:

#!/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

Wie Sie sehen können, akzeptiert dieses Skript zwei Argumente:Das erste ist der Benutzer (oder die Rolle), mit dem Sie sich für das Backup verbinden, während das zweite der Name der Datenbank ist, die Sie sichern möchten.

Beachten Sie die Option -C im Befehl, damit wir sie wiederherstellen können, falls die Datenbank nicht vorhanden ist, ohne sie vorher manuell erstellen zu müssen.

Rufen wir das Skript mit der Rolle postgres für die Datenbank example_backups auf (Vergessen Sie nicht, das Skript vor dem ersten Aufruf mindestens mit chmod +x ausführbar zu machen):

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

Und vergewissern Sie sich, dass es vorhanden ist:

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

Die Wiederherstellung wird mit diesem Sicherungsskript wie in den vorherigen Beispielen durchgeführt.

Ein ähnliches Shell-Skript kann mit pg_dumpall zum Sichern des gesamten PostgreSQL-Clusters verwendet werden.

Dieses Shell-Skript leitet (|) pg_dumpall an gzip weiter, das dann an einen bestimmten Dateispeicherort geleitet wird:

#!/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

Im Gegensatz zum vorherigen Beispielskript akzeptiert dieses keine Argumente.

Ich rufe dieses Skript in der Befehlszeile auf (keine Passwortabfrage, da die Postgres-Rolle die Datei ~/.pgpass verwendet – siehe Abschnitt oben.)

$ ~/My_Scripts/pgalldmp.sh

Wenn Sie fertig sind, liste ich den Inhalt des Verzeichnisses auf und zeige auch die Dateigrößen zum Vergleich zwischen den .sql- und gz-Dateien:

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

Ein Hinweis für das gz-Archivformat aus der Dokumentation:

„Die alternativen Archivdateiformate müssen mit pg_restore verwendet werden, um die Datenbank neu aufzubauen.“

Zusammenfassung

Ich habe wichtige Punkte aus der Dokumentation zu pg_dump und pg_dumpall zusammen mit meinen Beobachtungen zusammengestellt, um diesen Blogbeitrag abzuschließen:

Hinweis:Punkte aus der Dokumentation stehen in Anführungszeichen.

  • “pg_dump sichert nur eine einzelne Datenbank”
  • Das Klartext-SQL-Dateiformat ist die Standardausgabe für pg_dump.
  • Eine Rolle benötigt das SELECT-Privileg, um pg_dump gemäß dieser Zeile in der Dokumentation auszuführen:„pg_dump internally executes SELECT Statements. Wenn Sie Probleme beim Ausführen von pg_dump haben, stellen Sie sicher, dass Sie Informationen aus der Datenbank auswählen können, indem Sie beispielsweise psql verwenden.“
  • Um den erforderlichen DDL CREATE DATABASE-Befehl und eine Verbindung in die Sicherungsdatei aufzunehmen, fügen Sie die Option -C hinzu.
  • -W:Diese Option zwingt pg_dump, nach einem Passwort zu fragen. Dieses Flag ist nicht erforderlich, da Sie trotzdem aufgefordert werden, wenn der Server ein Kennwort erfordert. Trotzdem ist mir diese Passage in der Dokumentation aufgefallen, sodass ich dachte, sie hier aufzunehmen:„Allerdings verschwendet pg_dump einen Verbindungsversuch, um herauszufinden, dass der Server ein Passwort haben möchte. In einigen Fällen lohnt es sich, -W einzugeben, um den zusätzlichen Verbindungsversuch zu vermeiden.“
  • -d:Gibt die Datenbank an, zu der eine Verbindung hergestellt werden soll. Auch in der Dokumentation:„Dies entspricht der Angabe von dbname als erstes Nicht-Optionsargument in der Befehlszeile.“
  • Die Verwendung von Flags wie -t (Tabelle) ermöglicht es Benutzern, Teile der Datenbank zu sichern, nämlich Tabellen, für die sie Zugriffsrechte haben.
  • Sicherungsdateiformate können variieren. .sql-Dateien sind jedoch unter anderem eine gute Wahl. Sicherungsdateien werden von psql für eine Wiederherstellung wieder eingelesen.
  • pg_dump kann eine laufende, aktive Datenbank sichern, ohne andere Operationen (d. h. andere Leser und Schreiber) zu stören.
  • Eine Einschränkung:pg_dump sichert keine Rollen oder andere Datenbankobjekte einschließlich Tablespaces, sondern nur eine einzelne Datenbank.
  • Um Backups auf Ihrem gesamten PostgreSQL-Cluster zu erstellen, ist pg_dumpall die bessere Wahl.
  • pg_dumpall kann den gesamten Cluster verwalten und Informationen über Rollen, Tablespaces, Benutzer, Berechtigungen usw. sichern, wo pg_dump dies nicht kann.
  • Möglicherweise muss eine Rolle mit SUPERUSER-Berechtigungen den Dump durchführen und die Datei wiederherstellen/neu erstellen, wenn sie über psql wieder eingelesen wird, da während der Wiederherstellung die Berechtigung zum Lesen aller Tabellen in allen Datenbanken erforderlich ist.

Ich hoffe, dass ich durch diesen Blogbeitrag angemessene Beispiele und Details für einen Anfänger-Überblick über pg_dump und pg_dumpall für einzelne Entwicklungs-/Lern-PostgreSQL-Umgebungen bereitgestellt habe.

Obwohl nicht alle verfügbaren Optionen untersucht wurden, enthält die offizielle Dokumentation eine Fülle von Informationen mit Beispielen für beide Dienstprogramme, also stellen Sie sicher, dass Sie diese Ressource für weitere Studien, Fragen und Lektüre konsultieren.