Backup von PostgreSQL-Tabellen auf MagentaCloud per Shell-Skript

juedan

FreeBSDler
Hallo Forum,

bezugnehmend auf den Thread PostgreSQL:Backup habe ich ein Shell-Skript gebastelt, dass bis auf die Systemtabellen alle Tabellen von PostgreSQL-Datenbanken in einer MagentaCloud sichert. Vielleicht ist es ja für den einen oder anderen User interessant.

Code:
#!/bin/sh

# Shell-Skript als Cronjob fuer Backup aller Datenbanktabellen
# =========================================================
# Datum:      Ergaenzung:
# ---------------------------------------------------------
# 31.03.2020  Skript fertiggestellt

# ~/.netrc fuer MagentaCloud
# ---------------------------------------------------------
# machine webdav.magentacloud.de
# login MagentaCloud-Login
# password MagentaCloud-Password

# Magenta-Cloud
# ---------------------------------------------------------
mag_curl=`which curl`
mag_netrc="--netrc-file /home/admin/.netrc"
mag_target="https://webdav.magentacloud.de/PostgreSQL-Backup/"

# PostgreSQL-Kommandos
# ---------------------------------------------------------
pg_dump=`which pg_dump`
pg_sql=`which psql`
pg_userid="<userid>"
pg_host="localhost"
pg_sql_tables="SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';"
export PGPASSWORD="<password>"

# Allgemeine Variablen
# ---------------------------------------------------------
datum=`date "+%Y-%m-%d"`
datum_minus2tage=`date -v-2d "+%Y-%m-%d"`

backuppath="/home/backup/"

logfile=${backuppath}"backup.log"

# databases: alle Datenbanken durch Space getrennt eintragen
databases="bergtouren webcams wetter"

echo "Start Backup" > ${logfile}
date >> ${logfile}
echo "----------------------------" >> ${logfile}

for d in $databases; do
    echo "----------------------------" >> ${logfile}
    echo $d ":" >> ${logfile}
    echo "----------------------------" >> ${logfile}
    tables=`${pg_sql} -t -d $d -U ${pg_userid} -h ${pg_host} -c "${pg_sql_tables}"`

    for t in $tables; do
        echo $d " + " $t ":" >> ${logfile}
        backupfile="backup_${d}_${t}_$datum.zstd"
        echo ${backupfile} >> ${logfile}
        ${pg_dump} -h ${pg_host} -U ${pg_userid} -d $d -t $t -Fc | zstd > ${backuppath}${backupfile}
        if [ "$?" -ne 0 ]; then
            echo $d ":" $t " Dump konnte nicht erzeugt werden." >> ${logfile}
        else
            echo $d ":" $t " Dump wurde erzeugt." >> ${logfile}
        fi
        if [ -e "${backuppath}${backupfile}" ]; then
            result=`${mag_curl} ${mag_netrc} --anyauth --silent --show-error -T ${backuppath}${backupfile} ${mag_target}${backupfile} | grep '201 Created' | awk {'print substr($1, 8, 3)'}`
            echo "Meldung: " $result  >> ${logfile}
            if [ $result -gt 199 ] && [ $result -lt 300 ]; then
                echo $backupfile " Backup wurde uebertragen." >> ${logfile}
                backupfile_alt="pg_backup_${d}_${t}_$datum_minus2tage.zstd"
                if [ -e "${backuppath}${backupfile_alt}" ]; then
                    echo "loeschen auf server" >> ${logfile}
                    ${mag_curl} ${mag_netrc} --anyauth -X DELETE  ${mag_target}${backupfile}
                    rm -f ${backuppath}${backupfile_alt}
                    echo $backupfile_alt " Backup wurde geloescht." >> ${logfile}
                fi
            else
                echo $backupfile " Backup konnte nicht uebertragen werden." >> ${logfile}
            fi
        fi
    done
done

echo "----------------------------" >> ${logfile}
echo "Ende Backup:" >> ${logfile}
date >> ${logfile}
echo "----------------------------" >> ${logfile}

cat ${logfile} | mail -s "Database-Backup" <email-adresse admin>

Das Skript ist bestimmt nicht der Weisheit letzter Schluß und man kann bestimmt noch einige Dinge verbessern. Vielleicht ist es ja ein Grundgerüst für andere Ideen.

Beste Grüße und gesund bleiben!
 
Eine kleine Verbesserung habe ich noch:
statt
Code:
 | grep '201 Created' | awk {'print substr($1, 8, 3)'}
besser
Code:
-sw '%{http_code}'
 
Hallo zusammen,

wie ich feststellen durfte, geben einige Cloudsysteme beim Upload eine ausgeschmückte Erfolgsmeldung im HTML-Format zurück. Da funktioniert die Prüfung Variablen $result natürlich nicht mehr. Nach nochmaligem Studium der Man-Page zeigt sich, dass der zusätzliche Parameter
Code:
--output /dev/null
sehr hilfreich ist. Damit wird jetzt nur noch der HTTP-Returncode ermittelt und an $result übergeben.
 
wie ich feststellen durfte, geben einige Cloudsysteme beim Upload eine ausgeschmückte Erfolgsmeldung im HTML-Format zurück.

Die MagentaCloud vermag ich gerade nicht zu testen, aber du kannst mal curl um -H "Accept: application/json" anreichern. Viele APIs geben dann die Antwort in JSON statt HTML zurück, was sich z.B. mit jq schön auslesen lässt. Je nach Bedarf ist auch rclone einen Blick wert.

Wenn man mit solchen Anwendungsfällen anfängt, ist aber oftmals der Punkt erreicht, an dem sich der Wechsel zu Python o.ä. lohnt... ;)
 
Wenn man mit solchen Anwendungsfällen anfängt, ist aber oftmals der Punkt erreicht, an dem sich der Wechsel zu Python o.ä. lohnt... ;)
Ich habe lange überlegt, in welche Skript-Sprache ich nehmen soll. Ich bin dann zum Schluss gekommen, dass ein sh-Skript die beste Lösung ist, da ich keine Abhängigkeiten von irgendwas habe. Das Backup muss einfach funktionieren und cURL, psql und pg_dump liefern ja eh mundgerechte Ergebnisse - wenn man die man-Pages studiert :)
Dagegen ist das Skript zum Abgreifen der diversen Daten in PHP geschrieben, weil aus meiner Sicht der Datenbanksupport am besten implementiert ist. Aber gut, so wird jeder nach seiner Façon glücklich :)

Schönen Abend noch und gesund bleiben!
 
Zurück
Oben