고정 된 PostgreSQL 데이터베이스 백업 / 복원


156

Docker 웹 사이트에 설명 된대로 PostgreSQL 데이터베이스를 백업 / 복원하려고하는데 데이터가 복원되지 않습니다.

데이터베이스 이미지가 사용하는 볼륨은 다음과 같습니다.

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

이 명령으로 DB 컨테이너를 만듭니다.

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

이제 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 방법이지만, 도커 방법을 사용할 때 항상 선호해야한다고 생각합니다.
Carl Levasseur

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 명령 으로 바꾸고 cat결과 대신 docker exec로 파이프해야합니다 .
Tarion

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 폴더의 변경 사항을 감지하지 못합니다. 적어도 내가 감지하려는 변경 유형은 아닙니다.

첫 번째 해결책은 postgres 서버를 직접 시작하는 대신 bash로 컨테이너를 시작하고 데이터를 복원 한 다음 서버를 수동으로 시작하는 것입니다.

두 번째 해결책은 데이터 컨테이너를 사용하는 것입니다. 나는 전에 그 요점을 알지 못했지만 지금은 그렇게합니다. 이 데이터 컨테이너를 사용하면 postgres 컨테이너를 시작하기 전에 데이터를 복원 할 수 있습니다. 따라서 postgres 서버가 시작될 때 데이터가 이미 있습니다.


1
flocker 또는 convoy는 데이터 컨테이너 처리에 도움이 될 수 있습니다.
Forth

24
자세한 내용을 기입하십시오. 이것은 실제 솔루션보다 솔루션의 스케치처럼 들립니다.
nafg

5

또 다른 접근법 ( docker-postgresql-workflow 기반 )

로컬 실행중인 데이터베이스 (Docker가 아니지만 동일한 접근 방식이 작동합니다) :

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.psqldocker container bash
Sepultura

3

db_dump를 사용하여 db를 복원하려고 시도하는 동안이 문제가 발생했습니다. 나는 보통 dbeaver를 사용하여 복원하지만 psql 덤프를 받았으므로 docker 컨테이너를 사용하여 복원하는 방법을 찾아야했습니다.

Forth가 추천하고 Soviut이 편집 한 방법론이 저에게 효과적이었습니다.

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 파일에 의해 발생할 수 있습니다.이 문장의 정확성을 모르겠습니다. 따라서 Forth의 답변을 사용 하여이 파일을 찾지 못했습니다.

그런 다음 프로젝트와 함께 올바른 디렉토리로 이동하여 virtualenv를 활성화 한 다음 허용 된 답변을 실행했습니다. 붐, 정상처럼 일했다. 이것이 다른 누군가를 돕기를 바랍니다!



1

cat db.dump | docker exec ...내 덤프 (~ 2Gb)에서 작동하지 않았습니다. 몇 시간이 걸리고 메모리 부족 오류가 발생했습니다.

대신 컨테이너에 덤프하고 pg_restore를 사용했습니다.

컨테이너 ID가 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 이미지이므로 docker runDocker 레지스트리로 푸시하여 공유하거나 공유 할 수 있습니다.

(면책 조항 : 나는 프로젝트의 관리자입니다)


0

아래 명령은 docker postgress 컨테이너에서 덤프를 가져 오는 데 사용할 수 있습니다

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.