Sauvegarde et restauration d'une base de données sous PostgreSQL

Introduction

Dans ce module, on apprendra à sauvegarder une base de données et la restaurer par la suite.

Sauvegarde d'une base de données

Introduction

Pour cette partie nous allons nous concentrer sur une méthode de sauvegarde simple que nous propose PostgreSQL. Celle-ci est centré autour d'une commande : pg_dump.

Pour vous aider dans vos expérimentations, voici une liste de quelques commandes PostgreSQL basiques : https://stph.scenari-community.org/bdd/0/co/posUC001psql.html

Présentation de pg_dump

Le principe de cette technique est assez simple : générer un fichier de commandes SQL qui, lorsqu'elles sont exécutées sur une base de données vierge, permettent d'obtenir à l'identique la base de données sauvegardée.

Pour réussir cela, il sera d'abord nécessaire de se connecter à l'utilisateur postgres (sudo -i -u postgres) car il est nécessaire d'avoir les droits de super-utilisateur sur PostgreSQL pour que la sauvegarde se passe bien : le super-utilisateur est l'utilisateur dont on est sûr qu'il sera autorisé à lire toutes les tables de n'importe quelle base. Il est en effet nécessaire de lire les tables pour pouvoir les sauvegarder. Ainsi, nous connecter en tant que postgres nous garantit qu'on lira toutes les tables et que la sauvegarde sera complète.

Sauvegarde avec pg_dump

pg_dump -cC --file mon_fichier.dump nom_de_la_base

L'option -cC permettra de supprimer puis de récréer la base lors de la restauration, donc elle est à ne pas oublier.

Après avoir tapé cette commande, vous aurez donc un fichier de sauvegarde SQL.

Attention

Notons tout de même que si pendant la sauvegarde des changements sont faits sur la base de données, la sauvegarde ne les prendra pas en compte.

En revanche : « Les sauvegardes réalisées sont cohérentes, même lors d'accès concurrents à la base de données. pg_dump ne bloque pas l'accès des autres utilisateurs (ni en lecture ni en écriture). »

https://docs.postgresql.fr/current/app-pgdump.html

Remarque

Par convention on peut décider de mettre le fichier en .dump mais cela n'a aucune importance. Pour Unix, que vous mettiez .bak, .dump, .sql ou rien du tout, le système verra un fichier texte. Mettre .dump facilitera simplement la gestion des sauvegardes.

Exemple d'une sauvegarde

Si vous êtes familier au SQL, vous devez sûrement reconnaître, dans l'exemple ci-dessous, quelques commandes basiques telles que CREATE TABLE.

La lecture par PostgreSQL de l'ensemble de ces commandes permettra de faire qu'une base vierge devienne identique à la base sauvegardée.

Dans notre exemple, on voit la création de deux tables nommées array_int et pers.

--
-- PostgreSQL database dump
--
-- Dumped from database version 9.6.7
-- Dumped by pg_dump version 9.6.7
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: array_int; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE array_int (
    id integer[]
);
ALTER TABLE array_int OWNER TO postgres;
--
-- Name: pers; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE pers (
    test integer
);
ALTER TABLE pers OWNER TO postgres;
--
-- Data for Name: array_int; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY array_int (id) FROM stdin;
\.
--
-- Data for Name: pers; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY pers (test) FROM stdin;
\.
--
-- PostgreSQL database dump complete
--

Exemple d'une sauvegarde

On voit au début de ce fichier DROP et CREATE qui sont dus à l'utilisation de l'option -cC.

On voit également que le propriétaire de la base de données est défini.

Ici la base est vide donc on ne peut pas constater la création de tables et des insertions dans ces dernières..

--
-- PostgreSQL database dump
--
-- Dumped from database version 9.6.7
-- Dumped by pg_dump version 9.6.7
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
DROP DATABASE test;
--
-- Name: test; Type: DATABASE; Schema: -; Owner: postgres
--
CREATE DATABASE test WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'fr_FR.UTF-8' LC_CTYPE = 'fr_FR.UTF-8';
ALTER DATABASE test OWNER TO postgres;
\connect test
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
--
-- Name: SCHEMA public; Type: ACL; Schema: -; Owner: postgres
--
GRANT ALL ON SCHEMA public TO PUBLIC;
--
-- PostgreSQL database dump complete
--

Lecture d'une sauvegarde

Vous trouverez ci-dessous un fichier de sauvegarde. Il s'agit de la sauvegarde d'une base de données contenant une seule table. Grâce à un éditeur de texte, trouver le nom de la table.

Voici le contenu de la sauvegarde.

Vous trouverez ci-dessous un fichier de sauvegarde. Il s'agit de la sauvegarde d'une base de données contenant une seule table. Grâce à un éditeur de texte, trouver le nom de la table.

Voici le contenu de la sauvegarde.

rootme
CREATE TABLE rootme (
    id integer
);

Voici la commande contenue dans le fichier qui nous permet de connaître le nom de la table.

Restauration d'une base de données

Restauration d'une base de données à partir d'une sauvegarde

La restauration

Notre sauvegarde contenant la suppression et la création de la base, la restauration n'en sera que plus facile. Il suffira d'utiliser la commande psql avec l'option -f (qui déclenchera la lecture du fichier qui suit).

psql -f mon_fichier.dump

Après avoir entré cette commande, PostgreSQL lira le fichier et exécutera chacune des commandes.

RemarqueSi la base n'existe pas

Une erreur peut avoir lieu lors de l'exécution des commandes. En effet, si la base n'existe pas encore, une erreur s'affichera. Cependant, cela n'a aucune importance car le reste des commandes sera tout de même exécuté et la base sera crée telle qu'elle a été sauvegardé.

Vous trouverez ci-dessous un dump qu'il faudra restaurer dans une base de données vierge. Vous y trouverez une table nommée intro dans laquelle est présente une chaîne de caractère.

Quelle est-elle ?

Pour vous aider,  voici une commande SQL qui permet de sélectionner l'ensemble des lignes d'une table donnée :

SELECT * FROM intro ;

Vous trouverez ci-dessous un dump qu'il faudra restaurer dans une base de données vierge. Vous y trouverez une table nommée intro dans laquelle est présente une chaîne de caractère.

Quelle est-elle ?

Pour vous aider,  voici une commande SQL qui permet de sélectionner l'ensemble des lignes d'une table donnée :

SELECT * FROM intro ;

UTC

Voici la suite de commandes vous permettant d'arriver à ce résultat :

sudo -i -u postgres
createdb exo2
psql -f exo2.dump exo2
psql exo2
psql -c 'SELECT * FROM intro;' --username=postgres --dbname=exo2

Réalisation de scripts

Introduction

Pour les débutants qui n'ont jamais écrit de scripts shell, je vous propose de lire (et pourquoi pas de manipuler) les 4 premières courtes parties de ce tutoriel qui nous sera amplement suffisant pour réaliser des premiers scripts de sauvegarde.

Réalisation de scripts de sauvegarde

Création d'un répertoire récepteur des sauvegardes

Pour cette partie, on utilise toujours l'utilisateur Linux postgres (sudo -i -u postgres pour y accéder).

On va d'abord créer un répertoire de sauvegarde pour faciliter la gestion.

su #on se met en super-user (le mot de passe du root vous sera demander)
mkdir ./backups
chown postgres:postgres ./backups #on change le propriétaire du répertoire qui vient d'être créer
chmod 760 ./backups #on change les droits sur ce répertoire pour permettre à postgres de pouvoir faire ses sauvegardes dans celui-ci
exit

Exemple de script

Nous allons donc vous proposer un script des plus simples et le commenter :

#!/bin/bash
TODAY=$(date +%Y-%m-%d)
BACKDIR=/var/lib/postgresql/backups
pg_dump -cC --file $BACKDIR/$1_$TODAY.dump $1

Pour exécuter ce script, il suffira d'être connecté en tant que postgres et de lancer la commande suivante :

./backup.sh nom_de_la base à sauvegarder

Dans le script, $1 correspond au premier argument envoyé au script (ici, cet argument est le nom de la base de données).

Autre exemple pour une restauration

On va proposer un script qui permet de restaurer une sauvegarde dans une autre qui prendra deux arguments : le nom du fichier de sauvegarde ($1).

#!/bin/bash
BACKDIR=/var/lib/postgresql/backups
psql -f $BACKDIR/$1

Voici donc la commande à exécuter :

. /backup.sh fichier.dump nom_de_la_base

Compléments

Charger une sauvegarde dans une base de données existante

Lorsqu'on décide de ne pas utiliser la commande pg_dump avec les options -c et -C (autrement -cC), il y aura simplement les lignes de commandes pour remplir la base de données. Il sera donc possible de charger ce fichier sans problème dans une base de données qui se devra d'être vierge sinon vous aurez des incohérences.

La commande de sauvegarde reste la suivante mais sans le -cC:

pg_dump --file=test.dump testdb

Cependant, la restauration change un peu puisqu'il faut spécifier la base de données qui recevra la sauvegarde :

psql --file=test.dump base_vierge

Aller plus loin

Pour sauvegarder toutes les bases de données

pg_dumpall > mon_fichier.dump

Cette commande créera également un fichier de commande SQL mais pour sauvegarder l'ensemble des bases de données.

Maintenant, si vous désirez faire une restauration, il faudra un cluster. C'est un ensemble de bases de données qui partagent les mêmes ressources (processus, mémoire, disque...). Dès l'installation de PostgreSQL sur Debian, le système d'exploitation crée un cluster alors que d'autres systèmes demanderont d'en créer un manuellement.

Il vous faudra ensuite entrer la commande suivante pour restaurer sur le cluster vide :

psql -f mon_fichier.dump postgres

On utilise postgres comme base de données pour la restauration car lors de l'initialisation d'un cluster le super utilisateur et la base de données postgres sont crées.

ComplémentAutres sauvegardes possibles avec pg_dump

La commande pg_dump offre la possibilité de sauvegarder dans des formats autre qu'un fichier texte contenant des commandes SQL. On peut sauvegarder dans des formats d'archive nommés tar et custom.

Pour en savoir plus sur ceci, voilà un site qui vous apprendra à manipuler la sauvegarde et la restauration dans ces formats :

Complément

Pour mieux comprendre, les notions qui entourent ces sauvegardes, je vous invite à lire la page suivante :

https://stph.scenari-community.org/bdd/0/co/posUC106sch.html

Sauvegarde pour exercice

--
-- PostgreSQL database dump
--
-- Dumped from database version 9.6.7
-- Dumped by pg_dump version 9.6.7
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
DROP DATABASE exo1;
--
-- Name: exo1; Type: DATABASE; Schema: -; Owner: postgres
--
CREATE DATABASE exo1 WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'fr_FR.UTF-8' LC_CTYPE = 'fr_FR.UTF-8';
ALTER DATABASE exo1 OWNER TO postgres;
\connect exo1
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: rootme; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE rootme (
    id integer
);
ALTER TABLE rootme OWNER TO postgres;
--
-- Data for Name: rootme; Type: TABLE DATA; Schema: public; Owner: postgres
--
COPY rootme (id) FROM stdin;
\.
--
-- Name: SCHEMA public; Type: ACL; Schema: -; Owner: postgres
--
GRANT ALL ON SCHEMA public TO PUBLIC;
--
-- PostgreSQL database dump complete
--
Script Shell

Un fichier contenant des commandes pour le shell est appelé un script. C'est en fait un programme écrit dans le langage du shell. Ce langage comprend non seulement les commandes classiques tels que ls, rm,etc. , mais aussi des structures de contrôle (constructions conditionnelles et boucles).

Liste des raccourcis clavier

Liste des fonctions de navigation et leurs raccourcis clavier correspondant :

  • Bloc Suivant : flèche droite, flèche bas, barre espace, page suivante, touche N
  • Bloc Précédent : flèche gauche, flèche haut, retour arrière, page précédente, touche P
  • Diapositive Suivante : touche T
  • Diapositive Précédente : touche S
  • Retour accueil : touche Début
  • Menu : touche M
  • Revenir à l'accueil : touche H
  • Fermer zoom : touche Échap.