Backup / Ripristino di un database PostgreSQL dockerizzato


156

Sto cercando di eseguire il backup / ripristino di un database PostgreSQL come spiegato sul sito Web Docker, ma i dati non vengono ripristinati.

I volumi utilizzati dall'immagine del database sono:

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

e il CMD è:

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"]

Creo il contenitore DB con questo comando:

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

Quindi collego un altro contenitore per inserire manualmente alcuni dati:

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>

Viene quindi creato l'archivio tar:

$ 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

Ora rimuovo il contenitore usato per il db e ne creo un altro, con lo stesso nome, e provo a ripristinare i dati inseriti prima:

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

Ma le tabelle sono vuote, perché i dati non vengono ripristinati correttamente?


Risposte:


458

Eseguire il backup dei database

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

Ripristina i tuoi database

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

2
Sì, questo è il modo postgres per farlo, ma penso che il modo docker dovrebbe essere sempre preferito quando lo usi
Carl Levasseur,

42
Per risparmiare un po 'di spazio sul disco, potresti voler convogliare il dump su gzip: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > /var/data/postgres/backups/dump_data +% d-% m-% Y "_"% H_% M_% S.gz
Tarion

1
Basta decomprimere i dati prima di ripristinarli. Per farlo come un solo liner dovrai sostituire il cat your_dump.sqlcomando unzip con il comando pipe e pipe invece del catrisultato nel docker exec.
Tarion,

2
Il formato della data è incasinato, quindi ricontrolla prima di copiare e incollare.
vidstige,

1
Per quelli non riuscirebbero a capire come far funzionare la formattazione della data: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795

18

Penso che puoi anche utilizzare un contenitore di backup di Potgres che eseguirà il backup dei tuoi database entro un determinato periodo di tempo.

  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

1
Funziona perfettamente! Grazie
CaM2091,

15

Ok, l'ho capito. Postgresql non rileva le modifiche alla cartella / var / lib / postgresql una volta lanciato, almeno non il tipo di modifiche che voglio che rilevi.

La prima soluzione è avviare un contenitore con bash invece di avviare direttamente il server Postgres, ripristinare i dati e quindi avviare il server manualmente.

La seconda soluzione è utilizzare un contenitore di dati. Non l'ho capito prima, ora lo capisco. Questo contenitore di dati consente di ripristinare i dati prima di avviare il contenitore di Postgres. Pertanto, all'avvio del server Postgres, i dati sono già presenti.


1
flocker o convoy potrebbero aiutare nella gestione dei container di dati.
Forth

24
Si prega di compilare maggiori dettagli. Sembra più uno schizzo di una soluzione che una soluzione reale
nafg

5

Un altro approccio (basato su docker-postgresql-workflow )

Database in esecuzione locale (non nella finestra mobile, ma lo stesso approccio funzionerebbe) per esportare:

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

Database contenitore da importare:

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'

1
questo ha funzionato per me: pg_dump mydb -U postgres > export.psqlin docker container bash
Sepultura il

3

Ho riscontrato questo problema durante il tentativo di utilizzare un db_dump per ripristinare un db. Normalmente uso dbeaver per ripristinare, tuttavia ho ricevuto un dump psql, quindi ho dovuto trovare un metodo per ripristinare utilizzando il contenitore docker.

La metodologia raccomandata da Forth e curata da Soviut ha funzionato per me:

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

(dato che si trattava di un singolo db dump e non di più db ho incluso il nome)

Tuttavia, per far funzionare tutto questo, ho dovuto anche entrare nella virtualenv in cui si trovavano il contenitore e il progetto docker. Questo mi ha eluso per un po 'prima di capirlo - mentre stavo ricevendo il seguente errore docker.

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

Ciò può essere causato dal file /var/lib/docker/network/files/local-kv.db. Non conosco l'accuratezza di questa affermazione: ma credo che stavo vedendo questo dato che non uso docker utente localmente, quindi non aveva questo file, che stava cercando, usando la risposta di Forth.

Ho quindi navigato nella directory corretta (con il progetto) attivato virtualenv e quindi ho eseguito la risposta accettata. Boom, ha funzionato come un top. Spero che questo aiuti qualcun altro là fuori!



1

cat db.dump | docker exec ...modo non ha funzionato per il mio dump (~ 2Gb). Ci sono volute alcune ore e si è verificato un errore di memoria insufficiente.

Invece, ho chiuso la discarica in un contenitore e l'ho salvata dall'interno.

Supponendo che l'id contenitore sia CONTAINER_IDe il nome db sia 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

0

dksnap( https://github.com/kelda/dksnap ) automatizza il processo di esecuzione pg_dumpalle caricamento del dump tramite /docker-entrypoint-initdb.d.

Ti mostra un elenco di container in esecuzione e scegli quale vuoi fare il backup. Il manufatto risultante è una normale immagine Docker, quindi puoi quindi docker runcondividerla o spingerla in un registro Docker.

(disclaimer: sono un manutentore del progetto)


0

Il comando seguente può essere usato per prendere il dump dal contenitore postgress della finestra mobile

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.