Faça backup / restaure um banco de dados PostgreSQL com dockerized

155

Estou tentando fazer backup / restaurar um banco de dados PostgreSQL, conforme explicado no site do Docker, mas os dados não são restaurados.

Os volumes usados ​​pela imagem do banco de dados são:

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

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

Eu crio o contêiner DB com este comando:

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

Em seguida, conecto outro contêiner para inserir alguns dados manualmente:

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>

O arquivo tar é então criado:

$ 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

Agora, removo o contêiner usado para o banco de dados e crio outro, com o mesmo nome, e tento restaurar os dados inseridos antes:

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

Mas as tabelas estão vazias, por que os dados não são restaurados corretamente?

Carl Levasseur
fonte

Respostas:

457

Faça backup de seus bancos de dados

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

Restaure seus bancos de dados

cat your_dump.sql | docker exec -i your-db-container psql -U postgres
Adiante
fonte
2
Sim, isso é o postgres maneira de fazer isso, mas eu acho que a maneira janela de encaixe deve ser sempre preferido quando você usá-lo
Carl Levasseur
42
Para economizar espaço no disco, convém canalizar o dump para o 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 24/10/16
1
Apenas descompacte os dados antes de restaurá-los. Para fazer isso como um liner, você precisará substituir o cat your_dump.sqlcomando unzip e canalizar isso, em vez do catresultado para o docker exec.
Tarion
2
O formato da data está desarrumado, então verifique isso antes de copiar e colar.
vidstige
1
Para aqueles que não poderiam descobrir como obter a formatação da data de trabalho: docker exec -t your-db-container pg_dumpall -c -U postgres | gzip > ./tmp/dump_$(date +"%Y-%m-%d_%H_%M_%S").gz
user1230795
18

Eu acho que você também pode usar um contêiner de backup potgres que faria backup de seus bancos de dados dentro de um determinado período de 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
Tharindu Pradeep
fonte
1
Funciona perfeitamente ! Obrigado
CaM2091 28/01
15

Ok, eu descobri isso. O Postgresql não detecta alterações na pasta / var / lib / postgresql após o lançamento, pelo menos não o tipo de alteração que eu quero que ele detecte.

A primeira solução é iniciar um contêiner com bash, em vez de iniciar o servidor postgres diretamente, restaurar os dados e iniciar o servidor manualmente.

A segunda solução é usar um contêiner de dados. Eu não entendi direito antes, agora entendo. Este contêiner de dados permite restaurar os dados antes de iniciar o contêiner do postgres. Assim, quando o servidor postgres é iniciado, os dados já estão lá.

Carl Levasseur
fonte
1
flocker ou comboio pode ajudar no trato com o contêiner de dados.
Forth
24
Por favor, preencha mais detalhes. Isso soa mais como um esboço de uma solução do que uma solução real
nafg
5

Outra abordagem (baseada no docker-postgresql-workflow )

Banco de dados em execução local (não na janela de encaixe, mas a mesma abordagem funcionaria) para exportar:

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

Banco de dados de contêiner a ser importado:

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
fonte
1
Isso funcionou para mim: pg_dump mydb -U postgres > export.psqlem bash recipiente janela de encaixe
Sepultura
3

Eu tive esse problema ao tentar usar um db_dump para restaurar um db. Eu normalmente uso o dbeaver para restaurar - no entanto, recebi um despejo psql, então tive que descobrir um método para restaurar usando o contêiner do docker.

A metodologia recomendada por Forth e editada por Soviut funcionou para mim:

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

(uma vez que este era um único db dump e não vários db's, incluí o nome)

No entanto, para fazer com que isso funcionasse, eu também precisei entrar no ambiente virtual em que estavam o contêiner e o projeto do docker. Isso me escapou um pouco antes de descobrir, pois estava recebendo o seguinte erro do docker.

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

Isso pode ser causado pelo arquivo /var/lib/docker/network/files/local-kv.db .Não sei a precisão dessa declaração: mas acredito que estava vendo isso porque não utilizo a janela de encaixe localmente, portanto, não possuía esse arquivo, que estava procurando, usando a resposta de Forth.

Naveguei para o diretório correto (com o projeto), ativei o virtualenv e executei a resposta aceita. Boom, funcionou como um top. Espero que isso ajude alguém lá fora!

realidade
fonte
1

Este é o comando que funcionou para mim.

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

por exemplo

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

Referência : solução dada por GMartinez-Sisti nesta discussão. https://gist.github.com/gilyes/525cc0f471aafae18c3857c27519fc4b

Jacob Nelson
fonte
1

cat db.dump | docker exec ...O caminho não funcionou para o meu despejo (~ 2 GB). Demorou algumas horas e acabou com um erro de falta de memória.

Em vez disso, copiei o despejo no contêiner e o pg_restorei de dentro.

Supondo que o ID do contêiner seja CONTAINER_IDe o nome do banco de dados seja 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
fonte
0

dksnap( https://github.com/kelda/dksnap ) automatiza o processo de execução pg_dumpalle carregamento do dump via /docker-entrypoint-initdb.d.

Ele mostra uma lista de contêineres em execução e você escolhe qual deles deseja fazer backup. O artefato resultante é uma imagem regular do Docker, para que você possa docker runcompartilhá-lo ou enviá-lo para um registro do Docker.

(aviso: sou mantenedor do projeto)

Kevin Lin
fonte
0

O comando abaixo pode ser usado para fazer o despejo do contêiner do docker postgress

docker exec -t <postgres-container-name> pg_dump --no-owner -U <db-username> <db-name> > file-name-to-backup-to.sql
Shubham
fonte