Copiando o banco de dados PostgreSQL para outro servidor


492

Estou procurando copiar um banco de dados PostgreSQL de produção para um servidor de desenvolvimento. Qual é a maneira mais rápida e fácil de fazer isso?

Respostas:


668

Você não precisa criar um arquivo intermediário. Você pode fazer

pg_dump -C -h localhost -U localuser dbname | psql -h remotehost -U remoteuser dbname

ou

pg_dump -C -h remotehost -U remoteuser dbname | psql -h localhost -U localuser dbname

usando psqlou pg_dumppara conectar-se a um host remoto.

Com um grande banco de dados ou uma conexão lenta, despejar um arquivo e transferir o arquivo compactado pode ser mais rápido.

Como Kornel disse que não há necessidade de despejar em um arquivo intermediário, se você quiser trabalhar compactado, poderá usar um túnel compactado

pg_dump -C dbname | bzip2 | ssh  remoteuser@remotehost "bunzip2 | psql dbname"

ou

pg_dump -C dbname | ssh -C remoteuser@remotehost "psql dbname"

mas essa solução também requer uma sessão nos dois extremos.

Nota: pg_dump é para fazer backup e psqlpara restaurar. Portanto, o primeiro comando nesta resposta é copiar do local para o remoto e o segundo é do remoto para o local . Mais -> https://www.postgresql.org/docs/9.6/app-pgdump.html


28
Não há necessidade de arquivos intermediários - você pode usar o túnel SSH compactado ou simplesmente canalizar: pg_dump | bzip2 | ssh "bunzip2 | pg_restore"
— Kornel

4
Se você usa o bzip2, desative a compactação ssh para acelerar a transferência!
— lzap

8
Como posso trabalhar compactado se estou puxando dados da produção para o desenvolvimento? Eu configurei uma conexão SSH do desenvolvimento à produção. Então seria ssh remoteuser@remotehost "pg_dump -C dbname | bzip2" | bunzip2 | psql dbname?
— Jeromy French

2
Eu esperaria que você pudesse copiar um banco de dados remoto com o nome x para um banco de dados local com o nome y, mas a solução do @ Ferran não funciona para isso ... Parece-me que a solução do porneL apenas deixa os arquivos bzip2 no diretório servidor, então esse não é um processo de uma etapa. Sendo esse o caso, acho que vou largar o banco de dados y, usar a parte "ou" da solução de Ferran que restaura x e renomear o banco de dados para y.
— Darin Peterson

3
Foi o que fiz: (1) pg_dump -C -h remotehost -U remoteuser x | psql -h localhost -U localuser (2) dropdb y (3) psql -U postgres -c 'ALTER DATABASE "x" RENOMEAR PARA "y"'
— Darin Peterson

131
pg_dump the_db_name > the_backup.sql

Em seguida, copie o backup para o servidor de desenvolvimento, restaure com:

psql the_new_dev_db < the_backup.sql

3
Alguém me disse que isso pode ser problemático - problemas de permissões que fazem com que o dump ou a restauração morra quando ele dispara?
— Robin Barnes

17
@ rmbarnes: Se houver problemas - eles precisam ser corrigidos. Sem conhecimento detalhado do que esse "Alguém" fez - ninguém pode confirmar nem descartar essa alegação.

4
Use o sinalizador --no-owner com pg_dump. Isso pula o problema e a primeira edição deste post o usou - mas achei que você poderia precisar de uma fidelidade mais precisa ao banco de dados original.
— desmontado

4
Para mim, acima de abordagem funcionou na seguinte forma: pg_dump -C -h hospedeiro -U nome de usuário db_name> / any_directory / dump_schema_and_data_file .E para restaurar a partir do arquivo: -h hospedeiro psql -U nome de usuário db_name <dump_schema_and_data_file
— Ali Raza Bhayani

Isso me salvou MUITO agravamento. Eu usei o Google drive para mover o arquivo entre máquinas. Como eu já tinha o banco de dados na nova máquina (mas em branco), recebi muitos erros de chave duplicados. No entanto, é um ambiente de desenvolvimento e eles não machucaram nada.
— Chris Mendla

37

Use pg_dump e, posteriormente, psql ou pg_restore - dependendo se você escolhe as opções -Fp ou -Fc para pg_dump.

Exemplo de uso:

ssh production
pg_dump -C -Fp -f dump.sql -U postgres some_database_name
scp dump.sql development:
rm dump.sql
ssh development
psql -U postgres -f dump.sql

22

Se você deseja migrar entre versões (por exemplo, atualizou o postgres e possui 9.1 em execução no localhost: 5432 e 9.3 em execução no localhost: 5434), é possível executar:

pg_dumpall -p 5432 -U myuser91 | psql -U myuser94 -d postgres -p 5434

Confira os documentos de migração .


Me pediram a senha (myuser91 / postgres) várias vezes; existe uma maneira de eu precisar digitar a senha apenas uma vez?
— Martin Weber

@MartinWeber Crie um arquivo, pgpass de acordo com este documento postgresql.org/docs/9.4/static/libpq-pgpass.html
— Scott Warren

e se eles tiverem as mesmas portas?
— Ggnoredo

Se eles estiverem em servidores diferentes, você pode usar -h para especificar os hosts.
— Haroldo_OK

16

pg_basebackup parece ser a melhor maneira de fazer isso agora, especialmente para grandes bancos de dados.

Você pode copiar um banco de dados de um servidor com a mesma versão principal ou mais antiga. Ou, mais precisamente :

pg_basebackupfunciona com servidores da mesma ou de uma versão principal mais antiga, até a 9.1. No entanto, o modo de streaming WAL ( -X stream) funciona apenas com a versão 9.3 do servidor e posterior, e o modo de formato tar ( --format=tar) da versão atual funciona apenas com a versão 9.5 ou posterior do servidor.

Para isso, você precisa no servidor de origem:

  1. listen_addresses = '*'para se conectar a partir do servidor de destino. Verifique se a porta 5432 está aberta para esse assunto.
  2. Pelo menos 1 conexão de replicação disponível: max_wal_senders = 1( -X fetch), 2para -X stream(o padrão no caso do PostgreSQL 12) ou mais.
  3. wal_level = replicaou superior para poder definir max_wal_senders > 0.
  4. host replication postgres DST_IP/32 trustno pg_hba.conf. Isso concede acesso ao pgcluster a qualquer pessoa da DST_IPmáquina. Você pode querer recorrer a uma opção mais segura.

As alterações 1, 2, 3 requerem reinicialização do servidor, a alteração 4 requer recarga.

No servidor de destino:

# systemctl stop postgresql@VERSION-NAME
postgres$ pg_basebackup -h SRC_IP -U postgres -D VERSION/NAME --progress
# systemctl start postgresql@VERSION-NAME

11
Você poderia fornecer mais detalhes em sua resposta, como um exemplo?
— Magnilex

7
Isso só funciona quando ambas as máquinas têm as mesmas versões PG, no entanto.
— sm

As chances são pequenas de que você usaria uma versão diferente do banco de dados para desenvolvimento e produção. Na última vez, tive uma conversa desagradável com uma das minhas colegas de equipe, enquanto ela tentava enviar um problema de que algum código não está funcionando com o PG 9.6 enquanto tínhamos usado 9.5 na produção naquele momento. O backup da base é muito mais rápido. Então, pg_upgrade é o caminho a seguir, se necessário.
— Zorg

2
Provavelmente, você deseja migrar para uma versão mais recente e não deseja parar o PostgreSQL.
— X-yuri #

1
As chances são de que sempre que você atualiza seu banco de dados, você o atualiza no desenvolvimento e na preparação antes de fazê-lo na produção.
— andrew lorien

8

Execute este comando com o nome do banco de dados, que você deseja fazer backup, para obter o despejo de banco de dados.

 pg_dump -U {user-name} {source_db} -f {dumpfilename.sql}

 eg. pg_dump -U postgres mydbname -f mydbnamedump.sql

Agora scp este arquivo de despejo para a máquina remota onde você deseja copiar o banco de dados.

eg. scp mydbnamedump.sql user01@remotemachineip:~/some/folder/

Na máquina remota, execute o seguinte comando na pasta ~ / some / para restaurar o banco de dados.

 psql -U {user-name} -d {desintation_db}-f {dumpfilename.sql}

 eg. psql -U postgres -d mynewdb -f mydbnamedump.sql

7

Eu lutei bastante e, eventualmente, o método que me permitiu fazê-lo funcionar com o Rails 4 foi:

no seu servidor antigo

sudo su - postgres
pg_dump -c --inserts old_db_name > dump.sql

Eu tive que usar o usuário do postgres linux para criar o despejo. Também tive que usar -c para forçar a criação do banco de dados no novo servidor. --inserts diz para ele usar a sintaxe INSERT () que, de outra forma, não funcionaria para mim :(

então, no novo servidor, simpy:

sudo su - postgres
psql new_database_name < dump.sql

para transferir o arquivo dump.sql entre o servidor, simplesmente usei o "gato" para imprimir o conteúdo e depois o "nano" para recriá-lo copiando o conteúdo.

Além disso, o ROLE que eu estava usando no banco de dados dois era diferente, então tive que encontrar e substituir todo o nome do proprietário no despejo.


6

Despejar seu banco de dados: pg_dump database_name_name > backup.sql


Importe seu banco de dados de volta: psql db_name < backup.sql


5

Deixe-me compartilhar um script de shell do Linux para copiar os dados da tabela de um servidor para outro servidor PostgreSQL.

Referência retirada deste blog:

Script Linux Bash Shell para migração de dados entre servidores PostgreSQL:

#!/bin/bash
psql \
    -X \
    -U user_name \
    -h host_name1 \
    -d database_name \
    -c "\\copy tbl_Students to stdout" \
| \
psql \
    -X \
    -U user_name \
    -h host_name2 \
    -d database_name \
    -c "\\copy tbl_Students from stdin"

Estou apenas migrando os dados; crie uma tabela em branco no seu servidor de destino / segundo banco de dados.

Este é um script utilitário. Além disso, você pode modificar o script para uso genérico, como adicionar parâmetros para host_name, database_name, table_name e outros


5

A resposta aceita está correta, mas se você quiser evitar digitar a senha interativamente, pode usar o seguinte:

PGPASSWORD={{export_db_password}} pg_dump --create -h {{export_db_host}} -U {{export_db_user}} {{export_db_name}} | PGPASSWORD={{import_db_password}} psql -h {{import_db_host}} -U {{import_db_user}} {{import_db_name}}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.