Sichern / Wiederherstellen einer dockerisierten PostgreSQL-Datenbank

155

Ich versuche, eine PostgreSQL-Datenbank zu sichern / wiederherzustellen, wie auf der Docker-Website erläutert, aber die Daten werden nicht wiederhergestellt.

Die vom Datenbank-Image verwendeten Volumes sind:

VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

und die CMD ist:

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]

Ich erstelle den DB-Container mit diesem Befehl:

docker run -it --name "$DB_CONTAINER_NAME" -d "$DB_IMAGE_NAME"

Dann verbinde ich einen anderen Container, um einige Daten manuell einzufügen:

docker run -it --rm --link "$DB_CONTAINER_NAME":db "$DB_IMAGE_NAME" sh -c 'exec bash'
psql -d test -h $DB_PORT_5432_TCP_ADDR
# insert some data in the db
<CTRL-D>
<CTRL-D>

Das Teerarchiv wird dann erstellt:

$ sudo docker run --volumes-from "$DB_CONTAINER_NAME" --rm -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /etc/postgresql /var/log/postgresql /var/lib/postgresql

Jetzt entferne ich den für die Datenbank verwendeten Container und erstelle einen weiteren mit demselben Namen und versuche, die zuvor eingefügten Daten wiederherzustellen:

$ sudo docker run --volumes-from "$DB_CONTAINER_NAME" --rm -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar 

Aber die Tabellen sind leer. Warum werden die Daten nicht richtig wiederhergestellt?

Carl Levasseur
quelle

Antworten:

457

Sichern Sie Ihre Datenbanken

docker exec -t your-db-container pg_dumpall -c -U postgres > dump_`date +%d-%m-%Y"_"%H_%M_%S`.sql

Stellen Sie Ihre Datenbanken wieder her

cat your_dump.sql | docker exec -i your-db-container psql -U postgres
Viertens
quelle
2
Ja, das ist die Postgres-Methode, aber ich denke, die Docker-Methode sollte immer bevorzugt werden, wenn Sie sie verwenden
Carl Levasseur
41
Um Speicherplatz auf der Festplatte zu sparen, möchten Sie den Speicherauszug möglicherweise an gzip weiterleiten: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > /var/data/postgres/backups/dump_Datum +% d-% m-% Y "_"% H_% M_% S.gz
Tarion
1
Entpacken Sie einfach die Daten, bevor Sie sie wiederherstellen. Um dies als cat your_dump.sqlEinzeiler zu tun, müssen Sie den Befehl unzip durch den Befehl unzip ersetzen und diesen anstelle des catErgebnisses an docker exec weiterleiten .
Tarion
2
Das Datumsformat ist durcheinander. Überprüfen Sie dies, bevor Sie es kopieren und einfügen.
Vidstige
1
Für diejenigen, die nicht herausfinden konnten, wie die Datumsformatierung funktioniert: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795
18

Ich denke, Sie können auch einen Potgres-Sicherungscontainer verwenden, der Ihre Datenbanken innerhalb einer bestimmten Zeitdauer sichert.

  pgbackups:
    container_name: Backup
    image: prodrigestivill/postgres-backup-local
    restart: always
    volumes:
      - ./backup:/backups
    links:
      - db:db
    depends_on:
      - db
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_DB=${DB_NAME} 
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_EXTRA_OPTS=-Z9 --schema=public --blobs
      - SCHEDULE=@every 0h30m00s
      - BACKUP_KEEP_DAYS=7
      - BACKUP_KEEP_WEEKS=4
      - BACKUP_KEEP_MONTHS=6
      - HEALTHCHECK_PORT=81
Tharindu Pradeep
quelle
1
Funktioniert perfekt ! Danke
CaM2091
15

Okay, ich habe das herausgefunden. Postgresql erkennt nach dem Start keine Änderungen am Ordner / var / lib / postgresql, zumindest nicht die Art von Änderungen, die es erkennen soll.

Die erste Lösung besteht darin, einen Container mit Bash zu starten, anstatt den Postgres-Server direkt zu starten, die Daten wiederherzustellen und den Server dann manuell zu starten.

Die zweite Lösung besteht darin, einen Datencontainer zu verwenden. Ich habe es vorher nicht verstanden, jetzt schon. Mit diesem Datencontainer können die Daten wiederhergestellt werden, bevor der Postgres-Container gestartet wird. Wenn der Postgres-Server gestartet wird, sind die Daten bereits vorhanden.

Carl Levasseur
quelle
1
Flocker oder Konvoi können beim Umgang mit Datencontainern helfen.
Forth
24
Bitte geben Sie weitere Details ein. Dies klingt eher nach einer Skizze einer Lösung als nach einer tatsächlichen Lösung
nafg
5

Ein anderer Ansatz (basierend auf dem Docker-Postgresql-Workflow )

Lokale laufende Datenbank (nicht im Docker, aber der gleiche Ansatz würde funktionieren) zum Exportieren:

pg_dump -F c -h localhost mydb -U postgres export.dmp

Zu importierende Containerdatenbank:

docker run -d -v /local/path/to/postgres:/var/lib/postgresql/data postgres #ex runs container as `CONTAINERNAME` #find via `docker ps`
docker run -it --link CONTAINERNAME:postgres  --volume $PWD/:/tmp/  postgres  bash -c 'exec pg_restore -h postgres -U postgres -d mydb -F c /tmp/sonar.dmp'
sjakubowski
quelle
1
das hat bei mir funktioniert: pg_dump mydb -U postgres > export.psqlin docker container bash
Sepultura
3

Ich hatte dieses Problem beim Versuch, einen db_dump zum Wiederherstellen einer Datenbank zu verwenden. Normalerweise verwende ich dbeaver zum Wiederherstellen, habe jedoch einen psql-Speicherauszug erhalten und musste daher eine Methode zum Wiederherstellen mithilfe des Docker-Containers finden.

Die von Forth empfohlene und von Soviut bearbeitete Methodik hat für mich funktioniert:

cat your_dump.sql | docker exec -i your-db-container psql -U postgres -d dbname

(da dies ein einzelner DB-Dump war und nicht mehrere DBs, habe ich den Namen angegeben)

Um dies zum Laufen zu bringen, musste ich jedoch auch in die virtuelle Umgebung gehen, in der sich der Docker-Container und das Docker-Projekt befanden. Dies entging mir ein wenig, bevor ich es herausfand, da ich den folgenden Docker-Fehler erhielt.

read unix @->/var/run/docker.sock: read: connection reset by peer

Dies kann durch die Datei /var/lib/docker/network/files/local-kv.db verursacht werden. Ich kenne die Richtigkeit dieser Aussage nicht: aber ich glaube, ich habe dies gesehen, da ich Docker nicht lokal verwende. Daher hatte ich diese gesuchte Datei mit Forths Antwort nicht.

Ich habe dann zum richtigen Verzeichnis navigiert (mit dem Projekt), die virtuelle Umgebung aktiviert und dann die akzeptierte Antwort ausgeführt. Boom, arbeitete wie ein Top. Hoffe das hilft jemand anderem da draußen!

Aktivität
quelle
1

Dies ist der Befehl, der für mich funktioniert hat.

cat your_dump.sql | sudo docker exec -i {docker-postgres-container} psql -U {user} -d {database_name}

beispielsweise

cat table_backup.sql | docker exec -i 03b366004090 psql -U postgres -d postgres

Referenz : Lösung von GMartinez-Sisti in dieser Diskussion. https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b

Jacob Nelson
quelle
1

cat db.dump | docker exec ...Weg funktionierte nicht für meinen Dump (~ 2Gb). Es dauerte einige Stunden und führte zu einem Speicherfehler.

Stattdessen habe ich den Dump in den Container geschrieben und ihn von innen wiederhergestellt.

Angenommen, die Container-ID lautet CONTAINER_IDund der Datenbankname lautet DB_NAME:

# copy dump into container
docker cp local/path/to/db.dump CONTAINER_ID:/db.dump

# shell into container
docker exec -it CONTAINER_ID bash

# restore it from within
pg_restore -U postgres -d DB_NAME --no-owner -1 /db.dump
Alex Fedoseev
quelle
0

dksnap( https://github.com/kelda/dksnap ) automatisiert das Ausführen pg_dumpallund Laden des Dumps über/docker-entrypoint-initdb.d .

Es zeigt Ihnen eine Liste der laufenden Container und Sie wählen aus, welche Sie sichern möchten. Das resultierende Artefakt ist ein reguläres Docker-Image, sodass Sie es dann verwenden docker runoder freigeben können, indem Sie es in eine Docker-Registrierung verschieben.

(Haftungsausschluss: Ich bin ein Betreuer des Projekts)

Kevin Lin
quelle
0

Der folgende Befehl kann verwendet werden, um einen Speicherauszug aus dem Docker-Postgress-Container zu erstellen

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
Shubham
quelle