Cet article fait partie d’une série :

Introduction

Suite aux précédents articles sur les sauvegardes, cette 6ème partie traitera de la mise en place de la sauvegarde de bases de données PostgreSQL.

Le principe repose sur l’exécution d’un script sur le serveur à sauvegarder pour exporter et archiver les bases de données souhaitées, puis de l’ajout du chemin de stockage de ces archives dans la stratégie de sauvegarde de Restic (voir articles précédents).

L’ensemble des commandes sont à réaliser avec un utilisateur sudoer.

Script de sauvegarde

Créer le répertoire pour placer le script de sauvegarde (si celui-ci n’existe pas déjà) :

$ sudo -u restic mkdir /home/restic/scripts

Créer le script pgbackup_backup.sh dans le répertoire nouvellement créé.

Ce script part du postulat que le serveur de base de données est local, et ne nécessite donc pas de configuration particulière. Néanmoins, par défaut, il sauvegardera toutes les bases de données disponibles. Il est donc possible d’exclure certaines bases avec la variable exclude_dbs.

Pour le moment, le script a besoin d’être exécuté par l’utilisateur root, car l’utilisateur restic ne peut pas faire l’élévation de privilège nécessaire à l’excution de la commande pg_dump (accessible par l’utilisateur postgres).

Voir plus tard comment modifier cela avec la configuration de sudo.

#!/bin/bash
# A UNIX / Linux shell script to backup PostreSQL server database.
# Assume PostgreSQL server is local
# -------------------------------------------------------------------------
 
### Set to 1 if you need to see progress while dumping dbs ###
VERBOSE=0
 
### Set bins path ###
GZIP=/bin/gzip
PGSQL=/usr/bin/psql
PGDUMP=/usr/bin/pg_dump
RM=/bin/rm
MKDIR=/bin/mkdir
PGREADY=/usr/bin/pg_isready
GREP=/bin/grep
 
### Setup dump directory ###
BKPROOT=/tmp/bkp/pgsql
 
### List excluded DBS ###
exclude_dbs="template0 template1"

#####################################
### ----[ No Editing below ]------###
#####################################
### Default time format ###
TIME_FORMAT='%F-%H-%M-%S'

### Make a backup ###
backup_pgsql(){
        local DBS="$(sudo -u postgres ${PGSQL} -l | awk '{ print $1}' | grep -vE '^-|^List|^Name|^\||^\(')"
        local db="";
        [ ! -d $BKPROOT ] && ${MKDIR} -p $BKPROOT
        ${RM} -f $BKPROOT/* >/dev/null 2>&1
        [ $VERBOSE -eq 1 ] && echo "*** Dumping PostgreSQL Database ***"
        [ $VERBOSE -eq 1 ] && echo -n "Database> "
        for db in $DBS
        do
                if ! [[ " $exclude_dbs " =~ " $db " ]]
                then
                        local tTime=$(date +"${TIME_FORMAT}")
                        local FILE="${BKPROOT}/${db}.${tTime}.gz"
                        [ $VERBOSE -eq 1 ] && echo -n "$db.."
                        sudo -u postgres ${PGDUMP} $db | ${GZIP} -9 > $FILE
                fi
        done

        [ $VERBOSE -eq 1 ] && echo ""
        [ $VERBOSE -eq 1 ] && echo -n "Correcting permissions on backup files"
        chown -R restic: $BKPROOT

        status=$?
        [ $VERBOSE -eq 1 ] && echo ""
        [ $VERBOSE -eq 1 ] && echo "*** Backup done [ files wrote to $BKPROOT] ***"
        #if [ $VERBOSE -eq 0 ] && [ $status -eq 0 ]; then exit 0; fi
        return $status
}
 
### Die on demand with message ###
die(){
        echo "$@"
        exit 999
}
 
### Make sure bins exists.. else die
verify_bins(){
        [ ! -x $GZIP ] && die "File $GZIP does not exists. Make sure correct path is set in $0."
        [ ! -x $PGSQL ] && die "File $PGSQL does not exists. Make sure correct path is set in $0."
        [ ! -x $PGDUMP ] && die "File $PGDUMP does not exists. Make sure correct path is set in $0."
        [ ! -x $RM ] && die "File $RM does not exists. Make sure correct path is set in $0."
        [ ! -x $MKDIR ] && die "File $MKDIR does not exists. Make sure correct path is set in $0."
        [ ! -x $PGREADY ] && die "File $PGREADY does not exists. Make sure correct path is set in $0."
        [ ! -x $GREP ] && die "File $GREP does not exists. Make sure correct path is set in $0."
}
 
### Make sure we can connect to server ... else die
verify_pgsql_connection(){
        sudo -u postgres $PGREADY
        [ $? -eq 0 ] || die "Error: Cannot connect to Postgre Server. Make sure username and password are set correctly in $0"
}
 
### main ####
verify_bins
verify_pgsql_connection
backup_pgsql

Ajuster les permissions du script pour le rendre exécutable :

$ sudo chmod 700 /home/restic/scripts/pg_backup.sh 

Créer le répertoire temporaire de stockage des sauvegardes :

$ sudo mkdir -p /tmp/bkp/pgsql
$ sudo chown -R restic: /tmp/bkp

Automatisation

Créer un script cron :

$ sudo vim /etc/cron.d/pg_backup

Ajouter les lignes suivantes pour une exécution tous les jours à minuit :

# PostreSQL BKP
30 23   * * *   root    bash /home/restic/scripts/pg_backup.sh

Configuration de Restic

Ajouter le chemin (/tmp/bkp/pgsql) au paramètre BACKUP_PATHS du fichier de configuration des services (voir articles précédents).

Restauration

Recréer les bases et utilisateurs si vous restaurez sur une nouvelle installation.

Puis lancer la commande suivante pour restaurer une base :

$ gunzip backup_file.gz
$ psql -1 restored_database < backup_file

Sources