Utwórz kopię zapasową / przywróć zadokowaną bazę danych PostgreSQL

156

Próbuję wykonać kopię zapasową / przywrócić bazę danych PostgreSQL, jak wyjaśniono w witrynie Docker, ale dane nie są przywracane.

Woluminy używane przez obraz bazy danych to:

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

a CMD to:

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

Tworzę kontener DB za pomocą tego polecenia:

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

Następnie podłączam kolejny kontener aby ręcznie wstawić jakieś dane:

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>

Następnie tworzone jest archiwum 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

Teraz usuwam kontener używany dla bazy danych i tworzę kolejny, o tej samej nazwie i próbuję przywrócić dane wstawione wcześniej:

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

Ale tabele są puste, dlaczego dane nie są prawidłowo przywracane?

Carl Levasseur
źródło

Odpowiedzi:

457

Wykonaj kopię zapasową baz danych

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

Przywróć swoje bazy danych

cat your_dump.sql | docker exec -i your-db-container psql -U postgres
Naprzód
źródło
2
Tak, to jest sposób na postgres, ale myślę, że sposób dokowania powinien być zawsze preferowany, gdy go używasz
Carl Levasseur
42
Aby zaoszczędzić trochę miejsca na dysku, możesz docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > /var/data/postgres/backups/dump_.gz
przesłać
1
Po prostu rozpakuj dane przed ich przywróceniem. Aby zrobić to jako jedną linijkę, będziesz musiał zastąpić cat your_dump.sqlpolecenie unzip i potokować to zamiast catwyniku do docker exec.
Tarion
2
Format daty jest pomieszany, więc sprawdź to dokładnie przed skopiowaniem i wklejeniem.
vidstige
1
Dla tych, którzy nie mogliby wymyślić, jak uruchomić formatowanie daty: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795
18

Myślę, że możesz również użyć kontenera kopii zapasowych potgres, który utworzyłby kopię zapasową twoich baz danych w określonym czasie.

  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
źródło
1
Działa świetnie ! Dzięki
CaM2091
15

Okej, wymyśliłem to. Postgresql nie wykrywa zmian w folderze / var / lib / postgresql po uruchomieniu, a przynajmniej nie takich zmian, które chcę, aby wykrywał.

Pierwszym rozwiązaniem jest uruchomienie kontenera za pomocą bash zamiast bezpośredniego uruchamiania serwera postgres, przywrócenie danych, a następnie ręczne uruchomienie serwera.

Drugim rozwiązaniem jest użycie kontenera danych. Wcześniej nie rozumiałem, o co mi chodzi, teraz rozumiem. Ten kontener danych umożliwia przywrócenie danych przed uruchomieniem kontenera postgres. W związku z tym, gdy uruchamia się serwer postgres, dane już tam są.

Carl Levasseur
źródło
1
flocker lub convoy może pomóc w handlu kontenerami danych.
Czwarta
24
Proszę podać więcej szczegółów. To brzmi bardziej jak szkic rozwiązania niż rzeczywiste rozwiązanie
nafg
5

Inne podejście (oparte na docker-postgresql-workflow )

Lokalnie działająca baza danych (nie w dockerze, ale to samo podejście zadziała) do eksportu:

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

Baza danych kontenerów do zaimportowania:

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
źródło
1
to zadziałało dla mnie: pg_dump mydb -U postgres > export.psqlw docker container bash
Sepultura
3

Miałem ten problem podczas próby użycia db_dump do przywrócenia bazy danych. Zwykle używam programu dbeaver do przywracania - jednak otrzymałem zrzut psql, więc musiałem wymyślić metodę przywracania przy użyciu kontenera docker.

Pracowała dla mnie metodologia rekomendowana przez Forth i redagowana przez Soviut:

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

(ponieważ był to pojedynczy zrzut bazy danych, a nie wiele baz danych, zawarłem nazwę)

Jednak aby to zadziałało, musiałem również wejść do virtualenv, w którym znajdował się kontener docker i projekt. To wymknęło mi się na chwilę, zanim to rozgryzłem - ponieważ otrzymywałem następujący błąd dockera.

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

Może to być spowodowane plikiem /var/lib/docker/network/files/local-kv.db. Nie znam dokładności tego stwierdzenia: ale wydaje mi się, że widziałem to, ponieważ nie używam lokalnego dockera, więc nie miał tego pliku, którego szukał, korzystając z odpowiedzi Fortha.

Następnie przeszedłem do odpowiedniego katalogu (z projektem), aktywowałem virtualenv i uruchomiłem zaakceptowaną odpowiedź. Boom, działał jak top. Mam nadzieję, że to pomoże komuś innemu!

aktywna rzeczywistość
źródło
1

To polecenie zadziałało dla mnie.

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

na przykład

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

Odniesienie : Rozwiązanie podane przez GMartinez-Sisti w tej dyskusji. https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b

Jacob Nelson
źródło
1

cat db.dump | docker exec ...sposób nie działał dla mojego zrzutu (~ 2Gb). Zajęło to kilka godzin i zakończyło się błędem braku pamięci.

Zamiast tego zrzuciłem zrzut do kontenera i pg_restore'ed go od wewnątrz.

Zakładając, że identyfikator kontenera to, CONTAINER_IDa nazwa bazy danych to 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
źródło
0

dksnap( https://github.com/kelda/dksnap ) automatyzuje proces uruchamiania pg_dumpalli ładowania zrzutu przez /docker-entrypoint-initdb.d.

Pokazuje listę uruchomionych kontenerów i wybierasz, który chcesz zarchiwizować. Wynikowy artefakt jest zwykłym obrazem platformy Docker, więc możesz go następnie docker runudostępnić lub udostępnić, wypychając go do rejestru platformy Docker.

(zastrzeżenie: jestem opiekunem projektu)

Kevin Lin
źródło
0

Poniższe polecenie może służyć do pobrania zrzutu z kontenera postgress dockera

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
Shubham
źródło