PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Sauvegarder PostgreSQL à l'aide de pg_dump et pg_dumpall

Les entreprises et les services offrent une valeur basée sur les données. La disponibilité, l'état constant et la durabilité sont les principales priorités pour assurer la satisfaction des clients et des utilisateurs finaux. Des données perdues ou inaccessibles pourraient éventuellement être assimilées à des clients perdus.

Les sauvegardes de base de données doivent être au premier plan des opérations et des tâches quotidiennes.

Nous devons être préparés au cas où nos données seraient corrompues ou perdues.

Je crois fermement à un vieil adage que j'ai entendu :"Il vaut mieux l'avoir et ne pas en avoir besoin que d'en avoir besoin et ne pas l'avoir . "

Cela s'applique également aux sauvegardes de bases de données. Avouons-le, sans eux, vous n'avez pratiquement rien. Partir du principe que rien ne peut arriver à vos données est une erreur.

La plupart des SGBD fournissent des moyens d'utilitaires de sauvegarde intégrés. PostgreSQL a pg_dump et pg_dumpall prêts à l'emploi.

Les deux présentent de nombreuses options de personnalisation et de structuration. Les couvrir tous individuellement dans un seul article de blog serait presque impossible. Au lieu de cela, j'examinerai les exemples que je peux appliquer le mieux à mon environnement de développement personnel/d'apprentissage.

Cela étant dit, ce billet de blog n'est pas destiné à un environnement de production. Plus probablement, un seul poste de travail/environnement de développement devrait en bénéficier le plus.

Que sont pg_dump et pg_dumpall ?

La documentation décrit pg_dump comme :"pg_dump est un utilitaire de sauvegarde d'une base de données PostgreSQL"

Et la documentation pg_dumpall :"pg_dumpall est un utilitaire permettant d'écrire ("vider") toutes les bases de données PostgreSQL d'un cluster dans un seul fichier de script."

Sauvegarder une base de données et/ou des tables

Pour commencer, je vais créer une base de données d'entraînement et quelques tables avec lesquelles travailler en utilisant le SQL ci-dessous :

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)

La base de données et les tables sont toutes configurées.

A noter :

Dans beaucoup de ces exemples, je tirerai parti du \! de psql. méta-commande, vous permettant soit de passer dans un shell (ligne de commande), soit d'exécuter les commandes shell qui suivent.

Sachez simplement que dans un terminal ou une session de ligne de commande (indiqué par un '$' au début de cet article de blog), le \! La méta-commande ne doit être incluse dans aucune des commandes pg_dump ou pg_dumpall. Encore une fois, c'est une méta-commande pratique dans psql.

Sauvegarder une seule table

Dans ce premier exemple, je vais vider la seule table des étudiants :

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

En listant le contenu du répertoire, nous voyons que le fichier est là :

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

Les options de ligne de commande pour cette commande individuelle sont :

  • -U postgres :le nom d'utilisateur spécifié
  • -t étudiants :le tableau à vider
  • example_backups :la base de données

Qu'y a-t-il dans le fichier étudiants.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

Nous pouvons voir que le fichier contient les commandes SQL nécessaires pour recréer et repeupler la table des élèves.

Mais, est-ce que la sauvegarde est bonne ? Fiable et fonctionnel ?

Nous allons le tester et voir.

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

C'est parti.

Ensuite, depuis la ligne de commande, passez la sauvegarde enregistrée dans 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

Vérifions dans la base de données :

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)

Le tableau et les données ont été restaurés.

Sauvegarder plusieurs tables

Dans cet exemple suivant, nous allons sauvegarder les deux tables à l'aide de cette commande :

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

(Remarquez que j'avais besoin de spécifier un mot de passe dans cette commande en raison de l'option -W, ce que je n'avais pas fait dans le premier exemple. Plus d'informations à venir.)

Vérifions à nouveau que le fichier a été créé en listant le contenu du répertoire :

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

Déposez ensuite les tableaux :

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

Restaurez ensuite avec le fichier de sauvegarde 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)

Les deux tables ont été restaurées.

Comme nous pouvons le voir avec pg_dump, vous pouvez sauvegarder une ou plusieurs tables dans une base de données spécifique.

Sauvegarder une base de données

Voyons maintenant comment sauvegarder l'intégralité de la base de données example_backups avec 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

Le fichier ex_back_db.sql est là.

Je vais me connecter à la base de données postgres afin de supprimer la base de données example_backups.

postgres=# DROP DATABASE example_backups;
DROP DATABASE

Puis restaurez depuis la ligne de commande :

$ 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

Ce n'est pas là. Pourquoi pas? Et c'est où ?

Nous devons d'abord le créer.

postgres=# CREATE DATABASE example_backups;
CREATE DATABASE

Puis restaurez avec la même commande :

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

Base de données et toutes les tables présentes et prises en compte.

Nous pouvons éviter ce scénario consistant à créer d'abord la base de données cible en incluant l'option -C lors de la sauvegarde.

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

Je vais me reconnecter à la base de données postgres et supprimer la base de données example_backups afin que nous puissions voir comment la restauration fonctionne maintenant (notez que ces commandes connect et DROP ne sont pas affichées par souci de brièveté).

Puis sur la ligne de commande (notez qu'aucune option -d dbname n'est incluse) :

$ 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

En utilisant l'option -C, on nous demande un mot de passe pour établir une connexion comme mentionné dans la documentation concernant le drapeau -C :

"Commencez la sortie avec une commande pour créer la base de données elle-même et reconnectez-vous à la base de données créée."

Puis dans la session psql :

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

Tout est restauré, prêt à fonctionner et sans qu'il soit nécessaire de créer la base de données cible avant la restauration.

pg_dumpall pour l'ensemble du cluster

Jusqu'à présent, nous avons sauvegardé une seule table, plusieurs tables et une seule base de données.

Mais si nous voulons plus que cela, par exemple sauvegarder l'intégralité du cluster PostgreSQL, c'est là que nous devons utiliser pg_dumpall.

Alors, quelles sont les différences notables entre pg_dump et pg_dumpall ?

Pour commencer, voici une distinction importante par rapport à la documentation :

« Étant donné que pg_dumpall lit les tables de toutes les bases de données, vous devrez très probablement vous connecter en tant que superutilisateur de la base de données afin de produire un vidage complet. De plus, vous aurez besoin des privilèges de superutilisateur pour exécuter le script enregistré afin d'être autorisé à ajouter des utilisateurs et des groupes et à créer des bases de données. »

À l'aide de la commande ci-dessous, je vais sauvegarder l'intégralité de mon cluster PostgreSQL et l'enregistrer dans le fichier 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:

Que diable? Vous vous demandez si je devais saisir un mot de passe pour chaque invite ?

Oui, bien sûr. 24 fois.

Comptez-les. (Hé, j'aime explorer et me plonger dans différentes bases de données au fur et à mesure que j'apprends ? Que puis-je dire ?)

Mais pourquoi toutes ces invites ?

Tout d'abord, après tout ce travail acharné, est-ce que pg_dumpall a créé le fichier de sauvegarde ?

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

Oui, le fichier de sauvegarde est là.

Faisons la lumière sur toute cette 'pratique de frappe ' en regardant ce passage de la documentation :

« pg_dumpall doit se connecter plusieurs fois au serveur PostgreSQL (une fois par base de données). Si vous utilisez l'authentification par mot de passe, il vous demandera un mot de passe à chaque fois."

Je sais ce que vous pensez.

Ce n'est peut-être pas idéal ni même faisable. Qu'en est-il des processus, des scripts ou des tâches cron qui s'exécutent au milieu de la nuit ?

Quelqu'un va-t-il survoler le clavier en attendant de taper ?

Probablement pas.

Une mesure efficace pour éviter de faire face à ces demandes de mot de passe répétées est un fichier ~/.pgpass.

Voici la syntaxe dont le fichier ~/.pgpass a besoin pour fonctionner (exemple fourni à partir de la documentation voir lien ci-dessus) :

hostname:port:database:username:password

Avec un fichier ~/.pgpass présent dans mon environnement de développement, contenant les informations d'identification nécessaires pour le rôle postgres, je peux omettre l'option -W (également -w) et exécuter pg_dumpall sans m'authentifier manuellement avec le mot de passe :

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

Lister le contenu du répertoire :

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

Le fichier est créé et aucune demande de mot de passe répétitive.

Le fichier enregistré peut être rechargé avec psql similaire à pg_dump.

La base de données de connexion est également moins critique selon ce passage de la documentation :"Il n'est pas important de savoir à quelle base de données vous vous connectez ici puisque le fichier de script créé par pg_dumpall contiendra les commandes appropriées pour créer et se connecter aux bases de données enregistrées."

Téléchargez le livre blanc aujourd'hui PostgreSQL Management &Automation with ClusterControlDécouvrez ce que vous devez savoir pour déployer, surveiller, gérer et faire évoluer PostgreSQLTélécharger le livre blanc

pg_dump, pg_dumpall et scripts shell - Une combinaison pratique

Dans cette section, nous verrons quelques exemples d'incorporation de pg_dump et pg_dumpall dans des scripts shell simples.

Soyons clairs, il ne s'agit pas d'un didacticiel sur les scripts shell. Je ne suis pas non plus un gourou des scripts shell. Je vais principalement donner quelques exemples que j'utilise dans mon environnement de développement/d'apprentissage local.

Tout d'abord, examinons un simple script shell que vous pouvez utiliser pour sauvegarder une seule base de données :

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

Comme vous pouvez le voir, ce script accepte 2 arguments :le premier est l'utilisateur (ou le rôle) avec lequel se connecter pour la sauvegarde, tandis que le second est le nom de la base de données que vous souhaitez sauvegarder.

Notez l'option -C dans la commande afin que nous puissions restaurer si la base de données est inexistante, sans avoir besoin de la créer manuellement au préalable.

Appelons le script avec le rôle postgres pour la base de données example_backups (n'oubliez pas de rendre le script exécutable avec au moins chmod +x avant d'appeler pour la première fois) :

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

Et vérifiez qu'il est là :

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

La restauration est effectuée avec ce script de sauvegarde comme dans les exemples précédents.

Un script shell similaire peut être utilisé avec pg_dumpall pour sauvegarder l'intégralité du cluster PostgreSQL.

Ce script shell dirigera (|) pg_dumpall vers gzip, qui sera ensuite dirigé vers un emplacement de fichier désigné :

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

Contrairement à l'exemple de script précédent, celui-ci n'accepte aucun argument.

J'appellerai ce script sur la ligne de commande (pas d'invite de mot de passe puisque le rôle postgres utilise le fichier ~/.pgpass - Voir la section ci-dessus.)

$ ~/My_Scripts/pgalldmp.sh

Une fois terminé, je listerai le contenu du répertoire en indiquant également la taille des fichiers à des fins de comparaison entre les fichiers .sql et 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

Une note pour le format d'archive gz de la documentation :

"Les formats de fichier d'archive alternatifs doivent être utilisés avec pg_restore pour reconstruire la base de données."

Résumé

J'ai rassemblé les points clés de la documentation sur pg_dump et pg_dumpall, ainsi que mes observations, pour clore ce billet de blog :

Remarque :les points fournis à partir de la documentation sont entre guillemets.

  • "pg_dump ne vide qu'une seule base de données"
  • Le format de fichier SQL en texte brut est la sortie par défaut pour pg_dump.
  • Un rôle a besoin du privilège SELECT pour exécuter pg_dump selon cette ligne dans la documentation :"pg_dump exécute en interne des instructions SELECT. Si vous rencontrez des problèmes lors de l'exécution de pg_dump, assurez-vous que vous pouvez sélectionner des informations dans la base de données en utilisant, par exemple, psql"
  • Pour inclure la commande DDL CREATE DATABASE nécessaire et une connexion dans le fichier de sauvegarde, incluez l'option -C.
  • -W :cette option force pg_dump à demander un mot de passe. Cet indicateur n'est pas nécessaire car si le serveur requiert un mot de passe, vous êtes quand même invité. Néanmoins, ce passage dans la documentation a attiré mon attention alors j'ai pensé à l'inclure ici :« Cependant, pg_dump va gâcher une tentative de connexion en découvrant que le serveur veut un mot de passe. Dans certains cas, il vaut la peine de taper -W pour éviter la tentative de connexion supplémentaire."
  • -d :spécifie la base de données à laquelle se connecter. Également dans la documentation :"Cela équivaut à spécifier dbname comme premier argument non optionnel sur la ligne de commande."
  • L'utilisation d'indicateurs tels que -t (table) permet aux utilisateurs de sauvegarder des parties de la base de données, à savoir des tables, pour lesquelles ils disposent de privilèges d'accès.
  • Les formats des fichiers de sauvegarde peuvent varier. Cependant, les fichiers .sql sont un excellent choix parmi d'autres. Les fichiers de sauvegarde sont lus par psql pour une restauration.
  • pg_dump peut sauvegarder une base de données active en cours d'exécution sans interférer avec d'autres opérations (c'est-à-dire d'autres lecteurs et écrivains).
  • Une mise en garde :pg_dump ne vide pas les rôles ou les autres objets de la base de données, y compris les tablespaces, mais une seule base de données.
  • Pour effectuer des sauvegardes sur l'ensemble de votre cluster PostgreSQL, pg_dumpall est le meilleur choix.
  • pg_dumpall peut gérer l'intégralité du cluster, en sauvegardant les informations sur les rôles, les espaces de table, les utilisateurs, les autorisations, etc... là où pg_dump ne le peut pas.
  • Il y a de fortes chances qu'un rôle avec les privilèges SUPERUSER devra effectuer le vidage et restaurer/recréer le fichier lorsqu'il est relu via psql car pendant la restauration, le privilège de lire toutes les tables de toutes les bases de données est requis.

J'espère qu'à travers ce billet de blog, j'ai fourni des exemples et des détails adéquats pour un aperçu de niveau débutant sur pg_dump et pg_dumpall pour un seul environnement de développement/apprentissage PostgreSQL.

Bien que toutes les options disponibles n'aient pas été explorées, la documentation officielle contient une mine d'informations avec des exemples pour les deux utilitaires, alors assurez-vous de consulter cette ressource pour une étude plus approfondie, des questions et une lecture.