Ako zálohovať všetky Postgre databázy naraz

Už dlhšiu dobu som si lámal hlavu ako zálohovať všetky PostgreSQL databázy v jednom kroku tak aby som to nemusel robiť po jednej.

Na internete som našiel jedného chlapíka ktorý práve o tomto blogoval a ukázal tam aj riešenie.

Riešením tohto problému je jednoduchý shell skript ktorý zavolá root databázy (zväčša postgres). A tento skript vytvorí z každej databázy súbor s príponou .backup.

Shell skript ktorý som spomínal v mojom prípade nazvaný pg-backup-all-db.sh.

#!/bin/sh
# Posrgres executables
CMD_PSQL=/usr/bin/psql
CMD_DUMP=/usr/bin/pg_dump
# prefix for backup filenames
NAME_PREFIX=`date +%F`
# directory where to save the database backup
NAME_BACKUP_DIR=/srv/www/pgbackup/data
# age of the older file to keep (in days)
NB_DAYS_TO_KEEP=7
# Start backuping
Databases=`$CMD_PSQL -tq -d template1 -c "select datname from pg_database"`
echo "Starting backup of all databases..."
for current_db in `echo $Databases` 
do
  if [ "$current_db" != "template0" ] && [ "$current_db" != "template1" ]; then
    echo Backup $current_db to /$NAME_BACKUP_DIR/$NAME_PREFIX.$current_db.backup
    $CMD_DUMP -f /$NAME_BACKUP_DIR/$NAME_PREFIX.$current_db.backup $current_db
  fi
done
echo "Backup finnished !"
echo " "
# start deleting old file
echo "Deleteting old backup files..."
oldbackup=`find $NAME_BACKUP_DIR -type f -mtime +$NB_DAYS_TO_KEEP -name "*.backup"`
for current_file in `echo $oldbackup` 
do
  rm -f $current_file
  echo "$current_file deleted"
done
echo "Old file deletion finished !"
echo " "

Toto je takpovediac taký základ ktorým sa dajú zálohovať databázy. Ale čo ak je tých databáz naozaj veľa nie ako v mojom prípade 10 - 15 ale dajme tomu 200. To už je potom v tom priečinku potom riadny "bordel". A preto som tento skript rozšíril tak aby vytváral .tar.gz a to nasledovne:

#!/bin/sh
# Posrgres executables
CMD_PSQL=/usr/bin/psql
CMD_DUMP=/usr/bin/pg_dump
# prefix for backup filenames
NAME_PREFIX=`date +%F`
# directory where to save the database backup
NAME_BACKUP_TMP_DIR=/srv/www/pgbackup/data/$NAME_PREFIX
NAME_BACKUP_DIR=/srv/www/pgbackup/data
# create tmp directory
mkdir $NAME_BACKUP_TMP_DIR
echo "TMP directory $NAME_BACKUP_TMP_DIR has been created."
echo " "
# age of the older file to keep (in days)
NB_DAYS_TO_KEEP=14
# Start backuping
Databases=`$CMD_PSQL -tq -d template1 -c "select datname from pg_database"`
echo "Starting backup of all databases..."
for current_db in `echo $Databases`
do
  if [ "$current_db" != "template0" ] && [ "$current_db" != "template1" ]; then
    echo Backup $current_db to /$NAME_BACKUP_TMP_DIR/$NAME_PREFIX.$current_db.backup
    $CMD_DUMP -f /$NAME_BACKUP_TMP_DIR/$NAME_PREFIX.$current_db.backup $current_db
  fi
done
echo "Backup finnished !"
echo " "
# create tar
echo "Start TAR creating."
tar cvf $NAME_BACKUP_DIR/$NAME_PREFIX.tar $NAME_BACKUP_TMP_DIR
echo " "
echo "Tar $NAME_PREFIX.tar has been created."
echo " "
# create gzip
echo "Start GZIP creating."
gzip $NAME_BACKUP_DIR/$NAME_PREFIX.tar
echo "Gzip $NAME_PREFIX.tar.gz has been created."
echo " "
# delete tmp directory
rm -R $NAME_BACKUP_TMP_DIR
echo "TMP directory $NAME_PREFIX has been deleted."
echo " "
# start deleting old file
echo "Deleteting old backup files..."
oldbackup=`find $NAME_BACKUP_DIR -type f -mtime +$NB_DAYS_TO_KEEP -name "*.tar.gz"`
for current_file in `echo $oldbackup`
do
  rm -f $current_file
  echo "$current_file deleted"
done
echo "Old file deletion finished !"
echo " "

Ták teraz keď poznáme daný shell skript je inštalácia veľmi jednoduchá.

  1. Po spustení terminálu sa prepneme za root používateľa databázy postgres.
    su - postgres
  2. Pomocou príkazu vi alebo vim prípadne použitím iného textového editoru vytvoríme súbor ktorý bude obsahovať vyššie spomínaný shell script.
  3. Ďalej by som doporučoval z bezpečnostného hľadiska nastaviť práva len pre vlastníka súboru.
    chmod 700 [názov súboru]
  4. A nakoniec samozrejme daný shell skript spustiť.

V príde, že všetko funguje tak ako má môžeme tento skript nechať volať automaticky pomocou cronu ...

crontab -e

... do listu pridáme napríklad takýto riadok ...

30 4 1,15 * 5 /var/lib/pgsql/pg-backup-all-db.sh

... ktorý nám skript spustí o 4:30 1. a 15. deň v každom mesiaci, plus každý piatok.