Резервное копирование / восстановление докеризованной базы данных PostgreSQL

156

Я пытаюсь сделать резервную копию / восстановить базу данных PostgreSQL, как описано на сайте Docker, но данные не восстанавливаются.

Тома, используемые образом базы данных:

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

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

Я создаю контейнер БД с помощью этой команды:

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

Затем я подключаю другой контейнер, чтобы вставить некоторые данные вручную:

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>

Затем создается архив 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

Теперь я удаляю контейнер, используемый для БД, и создаю другой, с тем же именем, и пытаюсь восстановить данные, вставленные ранее:

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

Но таблицы пусты, почему данные не восстанавливаются должным образом?

Карл Левассер
источник

Ответы:

458

Резервное копирование ваших баз данных

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

Восстановите ваши базы данных

cat your_dump.sql | docker exec -i your-db-container psql -U postgres
вперед
источник
2
Да, это способ postgres сделать это, но я думаю, что докер всегда должен быть предпочтительным, когда вы его используете
Карл Левассер
42
Чтобы сэкономить место на диске, вы можете отправить дамп в gzip: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > /var/data/postgres/backups/dump_дата +% d-% m-% Y "_"% H_% M_% S.gz
Tarion
1
Просто распакуйте данные, прежде чем восстанавливать их. Чтобы сделать это как один вкладыш, вам придется заменить cat your_dump.sqlкоманду unzip и передать ее вместо catрезультата в docker exec.
Тарион
2
Формат даты испорчен, поэтому дважды проверьте это, прежде чем копировать и вставлять.
виджет
1
Для тех, кто не мог бы понять, как заставить работать форматирование даты: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795
18

Я думаю, что вы также можете использовать контейнер для резервного копирования Potgres, который будет резервировать ваши базы данных в течение определенного времени.

  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
Работает отлично! Спасибо
CaM2091
15

Хорошо, я понял это. Postgresql не обнаруживает изменения в папке / var / lib / postgresql после его запуска, по крайней мере, не те изменения, которые я хочу, чтобы он обнаруживал.

Первое решение - запустить контейнер с bash вместо прямого запуска сервера postgres, восстановить данные, а затем запустить сервер вручную.

Второе решение заключается в использовании контейнера данных. Я не понял этого раньше, теперь я понимаю. Этот контейнер данных позволяет восстановить данные перед запуском контейнера postgres. Таким образом, когда сервер postgres запускается, данные уже есть.

Карл Левассер
источник
1
Флокер или конвой могут помочь с обработкой контейнеров данных.
Forth
24
Пожалуйста, заполните более подробную информацию. Это больше похоже на набросок решения, чем на фактическое решение
nafg
5

Другой подход (основанный на docker-postgresql-workflow )

Локально работающая база данных (не в докере, но такой же подход будет работать) для экспорта:

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

База данных контейнера для импорта:

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
источник
1
это сработало для меня: pg_dump mydb -U postgres > export.psqlв доке контейнера Bash
Sepultura
3

У меня была эта проблема при попытке использовать db_dump для восстановления БД. Я обычно использую dbeaver для восстановления - однако получил дамп psql, поэтому мне пришлось придумать способ восстановления с помощью docker-контейнера.

Методология, рекомендованная Фортом и отредактированная Совиутом, сработала для меня:

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

(поскольку это был один дБ, а не несколько дБ, я включил имя)

Однако, чтобы заставить это работать, я должен был также перейти к virtualenv, в котором находились док-контейнер и проект. Это немного ускользнуло от меня, прежде чем я понял это, поскольку я получал следующую ошибку докера.

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

Это может быть вызвано файлом /var/lib/docker/network/files/local-kv.db. Я не знаю точности этого утверждения: но я считаю, что я видел это, поскольку я не использую docker локально, поэтому у него не было этого файла, который он искал, используя ответ Форта.

Затем я перешел в правильный каталог (вместе с проектом), активировал virtualenv и запустил принятый ответ. Бум, работал как волчок. Надеюсь, что это поможет кому-то еще там!

activereality
источник
1

Это команда работала для меня.

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

например

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

Ссылка : решение, данное GMartinez-Sisti в этом обсуждении. https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b

Джейкоб Нельсон
источник
1

cat db.dump | docker exec ...путь не работал для моего дампа (~ 2 Гб). Это заняло несколько часов и привело к ошибке нехватки памяти.

Вместо этого я скопировал дамп в контейнер и pg_restore'ed изнутри.

Предполагая, что идентификатор контейнера CONTAINER_IDи имя БД 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 ) автоматизирует процесс запуска pg_dumpallи загрузки дампа через /docker-entrypoint-initdb.d.

Он показывает вам список запущенных контейнеров, и вы выбираете, какой из них вы хотите сделать резервную копию. Получающийся в результате артефакт представляет собой обычный образ Docker, поэтому вы можете затем отправить docker runего или поделиться им, отправив его в реестр Docker.

(отказ от ответственности: я сопровождающий проекта)

Кевин Лин
источник
0

Приведенная ниже команда может быть использована для получения дампа из контейнера postgress docker

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
Shubham
источник