Резервне копіювання / відновлення докерізованої бази даних 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>

Потім створюється архів дьогтю:

$ 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

Тепер я виймаю контейнер, який використовується для db, і створюю ще один, з тим самим ім'ям, і намагаюся відновити введені раніше дані:

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

Але таблиці порожні, чому дані не відновлені належним чином?


Відповіді:


457

Резервне копіювання ваших баз даних

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_date +% d-% m-% Y "_"% H_% M_% S.gz
Tarion

1
Просто розпакуйте дані, перш ніж відновити їх. Щоб зробити це як один вкладиш, вам доведеться замінити cat your_dump.sqlкоманду unzip та pipe, яка замість catрезультату docker exec.
Таріон

2
Формат дати зіпсований, тому переконайтеся, що перед тим, як скопіювати та вставити.
vidstige

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
Будь ласка, заповніть більш детальну інформацію. Це звучить більше як ескіз рішення, ніж власне рішення
нафг

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'

1
це спрацювало для мене: pg_dump mydb -U postgres > export.psqlу докер-контейнері bash
Sepultura

3

У мене виникла ця проблема під час спроби використовувати db_dump для відновлення db. Я зазвичай використовую dbeaver для відновлення, однак отримав дамп psql, тому довелося з'ясувати метод відновлення за допомогою контейнера docker.

Методологія, рекомендована Forth та редагована Радянською мовою, працювала для мене:

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

(оскільки це був один db дамп, а не кілька db, я включив ім'я)

Однак, щоб змусити це працювати, мені довелося також зайти в virtualenv, що контейнер і проект докера були. Це трохи ухилилося від мене, перш ніж з'ясувати це, оскільки я отримував наступну помилку докера.

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

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

Потім я перейшов до виправлення каталогу (з проектом), активував virtualenv, а потім запустив прийняту відповідь. Бум, працював як топ. Сподіваюсь, це допомагає комусь іншому там!



1

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

Натомість я cp'ed скидаю в контейнер і pg_restore'ed його зсередини.

Якщо припустимо, що ідентифікатор контейнера CONTAINER_IDі ім'я db 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 runйого опублікувати або поділитися ним, натиснувши його до реєстру Докера.

(відмова від відповідальності: Я підтримую проект)


0

Наведена нижче команда може бути використана для вивантаження дампа з контейнера догресу докерів

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.