Skip to Main Content

 

Auswahl  

Postgres Backup einer Datenbank mit tar 

Postgres
Postgres
PG 13
04.06.20 (MP)
05.07.23(MP)
Postgres Backup

Passende Schulungen zum Thema

Wer seine Postgres Datenbank liebt/braucht, sollte regelmäßig ein Backup von ihr machen.
Der nachfolgende Tipp soll ein Skript dafür zur Verfügung stellen. Bitte testen Sie das Skript bitte ausgiebif durch bevor Sie es auf einer Produktiv-Datenbank ausführen.
Wir übernehmen keine Haftung/Gewähr für evtl Fehler.

export PG_BACKUP_PATH=/u01/pg/backup
export PG_DATABASE=postgres
export PG_DATA=/var/lib/pgsql/12/data
export PG_PATH=/usr/pgsql-12/bin
export PG_USER=postgres
export PG_ARCHIVE_PATH=/u01/pg/archivedir
export BACKUP_TIME=`date +"%Y_%m_%d_%H_%M_%S"`
export DAY_FOLDER=$PG_BACKUP_PATH/$BACKUP_TIME/PG_BAK_$BACKUP_TIME.tar.bz2

mkdir -p $PG_BACKUP_PATH/$BACKUP_TIME

echo "Starte Postgres Datenbank Backup (DB=$PG_DATABASE, Backup-Pfad=$PG_BACKUP_PATH/$BACKUP_TIME)"
WAL_START=`ls -rt1 $PG_ARCHIVE_PATH | tail -1`
BACKUP_START=`$PG_PATH/psql -q -U $PG_USER -d $PG_DATABASE -c "SELECT pg_start_backup('PG_BACKUP');" -P tuples_only -P format=unaligned`
BACKUP_START_TIME=`date +"%m.%d.%Y %H:%M:%S"`

if [ $? -ne 0 ]; then
  echo "PG Backup konnte nicht gestartet werden um `date`"
  exit 1;
fi
# Backup Befehl
cd $PG_DATA
tar -cjf $DAY_FOLDER --exclude='pg_wal' *
# Backup Befehl Ende

BACKUP_END=`$PG_PATH/psql -q -U$PG_USER -d $PG_DATABASE -c "SELECT pg_stop_backup();" -P tuples_only -P format=unaligned`

echo "Sichern der WAL´s ab $WAL_START"
find $PG_ARCHIVE_PATH -type f -newer $PG_ARCHIVE_PATH/$WAL_START  -exec cp {} $PG_BACKUP_PATH/$BACKUP_TIME \;
#zip -m $PG_BACKUP_PATH/$BACKUP_TIME/wal_files.zip $PG_BACKUP_PATH/$BACKUP_TIME/0*
cd $PG_BACKUP_PATH/$BACKUP_TIME
tar -cjf PG_WAL_$BACKUP_TIME.tar.bz2 0* --remove-files

######################################### R E S T O R E #####################

echo "Erstelle Restore Skript:$PG_BACKUP_PATH/$BACKUP_TIME/restore_$BACKUP_TIME.sh"
cat << EOF > $PG_BACKUP_PATH/$BACKUP_TIME/restore_$BACKUP_TIME.sh
export PG_BACKUP_PATH=$PG_BACKUP_PATH
export PG_DATABASE=$PG_DATABASE
export PG_DATA=$PG_DATA
export PG_PATH=$PG_PATH
export PG_USER=$PG_USER
export PG_ARCHIVE_PATH=$PG_ARCHIVE_PATH
export BACKUP_TIME=$BACKUP_TIME
EOF

cat << 'EOF' >> $PG_BACKUP_PATH/$BACKUP_TIME/restore_$BACKUP_TIME.sh
$PG_PATH/pg_ctl stop
mv $PG_DATA $PGDATA.old
mkdir -p $PG_DATA/pg_wal
chmod -R 700 $PG_DATA
cd $PG_BACKUP_PATH/$BACKUP_TIME
tar xvjf PG_BAK*.tar.bz2 -C $PG_DATA
if [ "$?" -ne 0 ]; then
        echo "Konnte DB nicht auspacken, Abbruch"
        exit;
fi
tar xvjf PG_WAL*.tar.bz2 -C $PG_DATA/pg_wal

if [ "$?" -ne 0 ]; then
        echo "Konnte WAL Dateien nicht auspacken, Abbruch"
        exit;
fi

touch $PG_DATA/recovery.signal
echo "Sie können recovern vom Zeit des Backups ($BACKUP_TIME) bis aktuell (latest)"
echo "Geben Sie das gewünschte Datum in der Form YYYY-MM-DD HH24:MI:SS an (z.B. 2020-06-23 15:34:01)"
read -p 'Zeitpunkt für Recovery: [latest]' -r RECOVER_TIME
RECOVER_TIME=${RECOVER_TIME:-latest}
if [ "$RECOVER_TIME" = "latest" ]; then
    echo "recovery_target_timeline = '$RECOVER_TIME'" >> $PG_DATA/postgresql.auto.conf
else
    echo "recovery_target_time = '$RECOVER_TIME'" >> $PG_DATA/postgresql.auto.conf
fi

echo "restore_command = 'cp /u01/pg/archivedir/%f %p'" >> $PG_DATA/postgresql.auto.conf
$PG_PATH/pg_ctl start
if [ "$?" -ne 0 ]; then
        cat `ls -tpr $PG_DATA/log | grep -v / | tail -n 1` | tail -10
fi
EOF
chmod u+x $PG_BACKUP_PATH/$BACKUP_TIME/restore_$BACKUP_TIME.sh

BACKUP_END_TIME=`date +"%m.%d.%Y %H:%M:%S"`
echo "Backup beendet: Start:$BACKUP_START_TIME Ende:$BACKUP_END_TIME "
echo "Größe/Ordner:`du -sh $PG_BACKUP_PATH/$BACKUP_TIME`"
ls -l  $PG_BACKUP_PATH/$BACKUP_TIME | awk {' print $6,$7,$8,$9'}


Kleine Erklärung zum Postgres Datenbank Backup Skript:

Im ersten Block werden die Variablen definiert. Prüfen Sie hier bitte, ob alle Voreinstellungen bei Ihnen passen.
in der Variablen WAL_START steht die letzte WAL-Datei vor dem Backup. Damit benötigen wir alle WAL Dateien, die danach angefallen sind, um das Backup wieder funktionstüchtig zu bekommen.
BACKUP_START setzt die Datenbank in den Backup-Modus. Das ist wichtig, weil wir danach erst Dateien aus der Datenbank Online kopieren dürfen.
Der Backup Befehl
tar -cjf $DAY_FOLDER --exclude='pg_wal' *
erzeugt ein Backup im Tar-Zip Format vom Hauptordner der Datenbank. Achtung: Eventuell vorhandene externe Tablespace-Ordner werden dadurch nicht mitkopiert!!!
BACKUP_END nimmt die Postgres Datenbank wieder aus dem Backupmodus heraus.

Der find Befehl findet alle nach Begin des Backups erzeugten WAL-Dateien und kopiert die auch in den Backup-Ordner.
Der nachfolgende Befehl packt die WAL Dateien auch in eine TAR-Datei.

Zusätzlich wird ein Restore Skript erzeugt. Dieses fragt sich beim Start auf welche Zeit denn zurückgesetzt werden soll. Wenn Sie auf den letztmöglichen Zeitpunkt zurückgehen möchten, geben Sie bitte latest ein.
Danach wird noch eine kleine Nachricht über den Erfolg des Backups ausgegeben.

HAPPY BACKUP

Für weitere Fragen rund um Postgres, besuchen Sie doch einen unserer Postgres-Kurse. 
 

Weitere Interessante Kurs-Tipps zum Thema

Trigger Beispiele in Postgres
Partitionierte Tabellen Beispiele in Postgres

Besuchen Sie uns doch bei einer unsere über 50 Oracle Schulungen in München - Unterhaching, oder verfolgen Sie die Training per Videostreaming bequem vom Home Office oder Büro aus.