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.