-
Notifications
You must be signed in to change notification settings - Fork 0
Manuelles Datenbank Backup
Um ein manuelles Backup der Postgres Datenbank zu erstellen gibt es mehrere Möglichkeiten, welche im Folgenden vorgestellt werden. Nach Betrachtung der Vor- und Nachteile wird abschließend eine Empfehlung gegeben.
Docker verwendet Volumes zur Persistierung von Daten außerhalb der eigentlichen Container. Durch die Speicherung auf dem Host-System bleiben die Daten auch nach Neustart des Containers erhalten. Um ein Datenbank-Backup zu erstellen, müssen diese Volumes gesichert und wiederhergestellt werden.
Bevor das Backup erstellt werden kann, sollte der entsprechende Container gestoppt werden (docker stop). Damit wird verhindert, dass während des Backup-Vorgangs Daten in die Datenbank geschrieben werden und es nicht zu einem inkonsistenten Backup kommt.
Anschließend kann mittels des folgenden Befehls ein Backup erstellt werden.
docker run -it --rm -v {volume_name}:/volume -v /tmp:/backup alpine \
tar -cjf /backup/{volume_name}.tar -C /volume ./
Dabei wird ein neuer Container erstellt, welcher das Volume des ursprünglichen Containers mounted (-v) und anschließend das Backup erstellt und als tar sichert.
Nachdem das Backup erstellt wurde, sollte dieses an einem geeigneten Ort abgelegt werden.
Project-Service:
docker run -it --rm -v project-db-data:/volume -v /tmp:/backup alpine \
tar -cjf /backup/project-db-data.tar -C /volume ./
Module-Service:
docker run -it --rm -v module-db-data:/volume -v /tmp:/backup alpine \
tar -cjf /backup/module-db-data.tar.bz2 -C /volume ./
Um das zuvor erstellte Backup wiederherzustellen, kann folgender Befehl ausgeführt werden:
docker run -it --rm -v {volume_name}:/volume -v /tmp:/backup alpine \
sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/{volume_name}.tar.bz2"
Identisch zum Erstellen wird auch hier ein neuer Container gestartet, welcher des ursprüngliche Volume aus dem Backup wiederherstellt.
Project-Service:
docker run -it --rm -v project-db-data:/volume -v /tmp:/backup alpine \
sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/project-db-data.tar.bz2"
Module-Service:
docker run -it --rm -v module-db-data:/volume -v /tmp:/backup alpine \
sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/module-db-data.tar.bz2"
Der Vorteil dieser Methode besteht darin, dass das Vorgehen unabhängig vom Inhalt des Volumes ist, also für alle Datenbanken angewendet werden kann. Zusätzlich kann dieses Vorgehen auch automatisiert werden, um in regelmäßigen Abständen Backups zu erstellen.
Der größte Nachteil dieser Methode besteht darin, dass der Docker Container für die Zeit des Backups gestoppt werden muss, was die Funktionalität des Services beeinträchtigen kann. Wenn für das Backup ein geeigneter Zeitpunkt gewählt wird, sollte dies aber für Prox kein großes Problem darstellen.
Quelle: Docker Volume
Eine weitere Möglichkeit besteht darin, ein Backup mittels SQL Dump zu erstellen. Dabei werden Teile oder die gesamte Datenbank (Struktur + Daten) in einer SQL Datei gesichert.
Zum Erstellen eines Backups wird der Befehl pg_dumpall direkt im Container ausgeführt:
docker exec -t {container_name} pg_dumpall -c -U {postgres_user} > dump.sql
In der Datei dump.sql werden alle SQL Commands gespeichert, um die aktuelle Datenbank vollständig wiederherzustellen. Mittels Clean (-c) wird das Skript erweitert, um beim Wiederherstellen alle vorherigen Daten zu löschen. Dadurch muss das Docker Volume nicht gelöscht werden, falls noch alte Daten vorhanden sind. Anschließend wird mittels -U der Benutzer angegeben, welcher das Backup ausführen soll. Nachdem das Backup erstellt wurde, sollte dieses an einem geeigneten Ort abgelegt werden, z.B. mittels SCP.
Project-Service:
docker exec -t ptb_project-db_1 pg_dumpall -c -U project-service > project_dump.sql
Module-Service:
docker exec -t ptb_module-db_1 pg_dumpall -c -U module-service > module_dump.sql
Um den SQL Dump wiederherzustellen, muss zuerst der Datenbank Container gestoppt werden, falls dieser noch läuft. Anschließend kann der folgende Befehl ausgeführt werden:
{type/cat} {dump_name} | docker exec -i {container_name} psql -U {postgres_user} -d {postgres_db}
Dabei wird das SQL Skript (Dump) direkt auf der Datenbank ausgeührt.
Project-Service:
cat project_dump.sql | docker exec -i ptb_project-db_1 psql -U project-service -d postgres
Module-Service:
cat module_dump.sql | docker exec -i ptb_module-db_1 psql -U module-service -d postgres
Anmerkung: Sollte es Fehler beim Wiederherstellen der Datenbank geben, ist der Grund dafür, dass noch Verbindungen zur Datenbank offen sind. Um diese zu beenden, kann folgender Code an den Beginn von dump.sql kopiert werden.
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'project-db' -- ← Name der Datenbank
AND pid <> pg_backend_pid();
Diese Methode ist sehr einfach auszuführen und das Backup (Dump) kann geöffnet werden, um die SQL Commands zu betrachten. Zusätzlich hat sich diese Methode bei der Entwicklung bewährt, um zusätzliche SQL Commands auf der Datenbank ausführen zu können, ohne die Migration mittels Flyway verwenden zu müssen und dadurch konnten einfach Daten in die Datenbank eingetragen werden. Wie auch bei der Sicherung der Docker Volumes kann diese Methode automatisiert werden. Ein weiterer Vorteil besteht darin, dass die SQL Dumps auch mittels Flyway wiederhergestellt werden können.
Der Nachteil dieser Methode besteht darin, dass sie für jeden Datenbanktyp angepasst werden muss. Da aber bei Prox immer nur Postgres Datenbanken verwendet werden, spielt dies keine große Rolle.
Quelle: Postgres Dump
Der Vollständigkeit halber gibt es noch eine weitere Möglichkeit. Mittels pgAdmin kann auch ein Backup erstellt und wiederhergestellt werden. Dafür ist aber ein direkter Datenbankzugriff und pgAdmin erforderlich.
Über einen Rechtsklick auf die Datenbank wird das Menü geöffnet, welches die Möglichkeit zum manuellen Backup bietet.
Um das Backup wiederherzustellen, muss zuerst eine neue Datenbank angelegt werden und anschließend kann mittels Rechtsklick auf die Datenbank die Restore Option gewählt werden.
Der Vorteil dieser Methode besteht darin, dass dadurch mit nur wenigen Klicks ein Backup erstellt werden kann. Für die Entwicklung mit einer lokalen Datenbank kann diese Methode hilfreich sein.
Wenn allerdings ein Backup im Live Betrieb erstellt werden soll, ist diese Methode eher ungeeignet. Zum einen ist ein direkter Datenbankzugriff erforderlich (was zumindest für uns im GP nicht möglich war) und zum anderen kann dieses Vorgehen nicht automatisiert werden.
Die eigentliche Aufgabe war es, die Möglichkeit eines manuellen Backups zu untersuchen, dies ist mittels pgAdmin sehr einfach. Aber ausgehend von der Tatsache, dass das Vorgehen später wahrscheinlich automatisiert werden soll, ist diese Methode nur für die lokale Entwicklung geeignet.
Die anderen beiden Methoden lassen sich automatisieren und können beide eingesetzt werden. Der Nachteil, dass die Container während der Sicherung gestoppt werden müssen, spielt bei der Sicherung der Docker Volumes für Prox keine große Rolle. Der Vorteil, dass alle Volumes gleich behandelt werden können, kommt aber auch nicht zum Tragen, da nur Postgres Datenbanken verwendet werden.
Wenn es nur um die Sicherung der Datenbanken geht, ist wohl die Methode zur Erstellung des SQL Dumps die Einfachste. Diese hat sich zumindest während der Entwicklung als praktikabel erwiesen und wurde bei der Recherche zur Sicherung von Postgres Datenbanken in Docker als favorisierte Methode dargestellt.