15 min de leitura · Guia técnico
Migrar banco de dados PostgreSQL pela linha de comando consiste em exportar o dump do banco de origem com pg_dump e restaurá-lo no servidor de destino com psql ou pg_restore, sem necessidade de interface gráfica. Para migrar PostgreSQL usando apenas o terminal, siga estes passos:
- Instale o cliente PostgreSQL no servidor de destino e verifique a conectividade entre os servidores.
- Crie o banco de dados de destino com encoding e locale corretos usando
createdb. - Exporte o banco de origem com
pg_dumpno formato custom (-Fc). - Transfira o arquivo de dump para o servidor de destino via
scpou pipe direto via SSH. - Restaure o dump no banco de destino com
pg_restore. - Valide a integridade dos dados comparando contagem de registros e estrutura de tabelas.
Pré-requisitos para migrar PostgreSQL entre servidores
- Acesso SSH root ou sudo nos dois servidores (origem e destino).
- PostgreSQL instalado no servidor de destino — versão 14, 15 ou 16 (Debian 12, Rocky Linux 9 ou AlmaLinux 9).
- Cliente PostgreSQL (
postgresql-client) disponível no servidor de origem para executarpg_dump. - Espaço em disco suficiente no destino: ao menos 2x o tamanho do banco de origem para acomodar o dump e a restauração simultânea.
- Porta 5432 liberada no firewall do servidor de destino, ou acesso via SSH para transferência do arquivo de dump.
- Credenciais do superusuário PostgreSQL (
postgres) em ambos os servidores. - Conhecimento básico de como acessar servidores Linux — consulte o guia Acessando servidores VPS Linux da AviraHost se precisar de ajuda com SSH.
Como exportar o banco de dados PostgreSQL com pg_dump
O pg_dump é a ferramenta nativa do PostgreSQL para exportar bancos de dados de forma consistente, sem bloquear leituras ou escritas em andamento. Ao rodar este comando, você verá o arquivo de dump sendo gerado no diretório especificado — o formato -Fc (custom) é o mais recomendado para migrações porque suporta restauração paralela e compressão nativa.
No servidor de origem, execute os comandos abaixo como usuário postgres:
sudo -u postgres pg_dump -Fc -v -d nome_do_banco -f /tmp/backup_nome_do_banco.dump
Explicação dos parâmetros:
- -Fc: formato custom comprimido, compatível com
pg_restore. - -v: modo verbose — exibe o progresso da exportação no terminal.
- -d nome_do_banco: nome do banco a ser exportado.
- -f /tmp/backup_nome_do_banco.dump: caminho de saída do arquivo.
Output esperado ao final da exportação:
pg_dump: saving encoding = UTF8
pg_dump: saving standard_conforming_strings = on
pg_dump: saving search_path =
pg_dump: finished item 1234 TABLE DATA public.nome_da_tabela
pg_dump: dumping contents of table "public.nome_da_tabela"
pg_dump: finished main parallel loop
Para verificar o tamanho do dump gerado:
ls -lh /tmp/backup_nome_do_banco.dump
-rw-r--r-- 1 postgres postgres 142M jan 15 14:32 /tmp/backup_nome_do_banco.dump
Se o banco contiver objetos grandes (BLOBs), adicione a flag -b ao comando pg_dump para incluí-los no dump.
Transferindo o dump para o servidor de destino via SSH
A transferência segura do arquivo de dump é uma etapa crítica na migração de banco de dados PostgreSQL. O método mais simples é o scp, que usa o protocolo SSH para copiar arquivos entre servidores sem expor dados em texto puro.
No servidor de origem, execute:
scp /tmp/backup_nome_do_banco.dump usuario@IP_DESTINO:/tmp/backup_nome_do_banco.dump
Substitua usuario pelo usuário SSH do servidor de destino e IP_DESTINO pelo endereço IP ou hostname do servidor de destino.
Output esperado durante a transferência:
backup_nome_do_banco.dump 100% 142MB 18.3MB/s 00:07
Alternativa mais eficiente — pipe direto via SSH: este método exporta e restaura em um único comando, sem gravar o arquivo intermediário em disco. É ideal quando o espaço em disco é limitado:
sudo -u postgres pg_dump -Fc nome_do_banco | ssh usuario@IP_DESTINO "sudo -u postgres pg_restore -d nome_do_banco_destino"
Para bancos muito grandes, considere usar rsync com compressão adicional:
rsync -avz --progress /tmp/backup_nome_do_banco.dump usuario@IP_DESTINO:/tmp/
Criando o banco de destino e restaurando com pg_restore
Antes de restaurar o dump, é necessário criar o banco de dados no servidor de destino com o encoding e locale corretos. Esta etapa garante que caracteres especiais do português — como acentos e cedilha — sejam armazenados corretamente após a restauração do PostgreSQL.
No servidor de destino, conecte ao PostgreSQL como superusuário e crie o banco:
sudo -u postgres psql -c "CREATE DATABASE nome_do_banco ENCODING 'UTF8' LC_COLLATE 'pt_BR.UTF-8' LC_CTYPE 'pt_BR.UTF-8' TEMPLATE template0;"
Output esperado:
CREATE DATABASE
Atenção: o uso de TEMPLATE template0 é obrigatório quando se especifica encoding ou locale diferente do padrão do cluster. Sem ele, o PostgreSQL retornará erro de incompatibilidade de locale.
Agora restaure o dump com pg_restore:
sudo -u postgres pg_restore -v -d nome_do_banco /tmp/backup_nome_do_banco.dump
Para restauração paralela (mais rápida em bancos grandes), use a flag -j com o número de CPUs disponíveis:
sudo -u postgres pg_restore -v -j 4 -d nome_do_banco /tmp/backup_nome_do_banco.dump
Output esperado ao final:
pg_restore: creating TABLE "public.nome_da_tabela"
pg_restore: creating INDEX "public.idx_nome_da_tabela_campo"
pg_restore: creating CONSTRAINT "public.nome_da_tabela_pkey"
pg_restore: finished main parallel loop
Se o banco de destino já existir e você quiser sobrescrever os dados, adicione --clean ao comando pg_restore para remover objetos existentes antes de recriar:
sudo -u postgres pg_restore -v --clean -d nome_do_banco /tmp/backup_nome_do_banco.dump
Migrando roles e permissões do PostgreSQL
Um ponto frequentemente esquecido na exportação e importação de banco PostgreSQL é a migração dos roles (usuários e grupos) e suas permissões. O pg_dump exporta apenas os dados e a estrutura do banco — os roles globais do cluster precisam ser migrados separadamente com pg_dumpall.
No servidor de origem, exporte apenas os roles globais (sem os dados dos bancos):
sudo -u postgres pg_dumpall --roles-only -f /tmp/roles.sql
Transfira o arquivo para o destino:
scp /tmp/roles.sql usuario@IP_DESTINO:/tmp/roles.sql
No servidor de destino, importe os roles:
sudo -u postgres psql -f /tmp/roles.sql
Output esperado:
CREATE ROLE
ALTER ROLE
CREATE ROLE
ALTER ROLE
Após importar os roles, verifique se foram criados corretamente:
sudo -u postgres psql -c "\du"
List of roles
Role name | Attributes | Member of
-----------+-------------------------------------------------------------+-----------
app_user | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
readonly | Cannot login | {}
Para referência sobre como conectar remotamente ao PostgreSQL após a migração, consulte o artigo Conectando remotamente ao PostgreSQL - cPanel.
Validando a integridade dos dados após a migração
A verificação pós-migração do PostgreSQL é tão importante quanto a própria migração. Antes de apontar sua aplicação para o novo servidor, confirme que todos os dados foram transferidos corretamente comparando registros entre origem e destino.
No servidor de destino, conecte ao banco migrado:
sudo -u postgres psql -d nome_do_banco
Liste todas as tabelas para confirmar que a estrutura foi restaurada:
\dt
List of relations
Schema | Name | Type | Owner
--------+-------------------+-------+----------
public | clientes | table | app_user
public | pedidos | table | app_user
public | produtos | table | app_user
(3 rows)
Compare a contagem de registros de tabelas críticas entre origem e destino:
SELECT count(*) FROM clientes;
SELECT count(*) FROM pedidos;
SELECT count(*) FROM produtos;
Execute também uma verificação de sequências, que frequentemente ficam desincronizadas após restauração:
SELECT sequence_name, last_value FROM information_schema.sequences
JOIN pg_sequences ON sequencename = sequence_name;
Se alguma sequência estiver desatualizada, redefina-a manualmente:
SELECT setval('public.clientes_id_seq', (SELECT MAX(id) FROM clientes));
Por fim, verifique se há erros nos logs do PostgreSQL no servidor de destino:
sudo tail -50 /var/log/postgresql/postgresql-16-main.log
Problemas comuns e como resolver
Sintoma: erro "role does not exist" durante o pg_restore
Causa: o dump referencia roles (usuários) que existem no servidor de origem mas não foram criados no destino antes da restauração.
Solução: exporte e importe os roles com pg_dumpall --roles-only antes de executar o pg_restore, conforme descrito na seção de migração de roles. Alternativamente, adicione --no-owner e --no-privileges ao pg_restore para ignorar a atribuição de proprietários durante a restauração:
sudo -u postgres pg_restore -v --no-owner --no-privileges -d nome_do_banco /tmp/backup_nome_do_banco.dump
Sintoma: erro "invalid encoding name" ou dados com caracteres corrompidos
Causa: o banco de destino foi criado com encoding diferente do banco de origem, ou o locale pt_BR.UTF-8 não está instalado no sistema operacional do servidor de destino.
Solução: primeiro, verifique se o locale está disponível no sistema:
locale -a | grep pt_BR
Se não estiver listado, gere o locale no Debian/Ubuntu:
sudo locale-gen pt_BR.UTF-8
sudo update-locale
No Rocky Linux 9 ou AlmaLinux 9:
sudo dnf install glibc-langpack-pt -y
Depois, recrie o banco de destino com o encoding correto antes de restaurar novamente.
Sintoma: pg_restore trava ou fica lento em bancos grandes
Causa: a restauração sequencial de bancos com muitos índices e constraints é lenta porque o PostgreSQL valida cada constraint após cada inserção.
Solução: use restauração paralela com -j e desative temporariamente a sincronização de disco para acelerar o processo. No arquivo postgresql.conf do servidor de destino, ajuste temporariamente:
synchronous_commit = off
fsync = off
Atenção: reative fsync = on e synchronous_commit = on imediatamente após a restauração. Manter essas configurações desativadas em produção pode causar corrupção de dados em caso de falha de energia.
Sintoma: conexão recusada ao tentar acessar o PostgreSQL no servidor de destino
Causa: o PostgreSQL no servidor de destino está configurado para aceitar conexões apenas de localhost, ou o firewall está bloqueando a porta 5432.
Solução: edite o arquivo pg_hba.conf para permitir conexões do IP de origem e reinicie o serviço:
sudo nano /etc/postgresql/16/main/pg_hba.conf
Adicione a linha:
host nome_do_banco app_user IP_ORIGEM/32 md5
sudo systemctl restart postgresql
Perguntas frequentes sobre migração de banco de dados PostgreSQL
É possível migrar PostgreSQL sem parar o servidor de origem?
Sim, o pg_dump realiza um dump consistente sem bloquear leituras no banco de origem. Para bancos com escrita intensa, recomenda-se agendar a migração em horário de baixo tráfego ou usar replicação lógica para migração com downtime zero. A replicação lógica permite que o banco de destino fique sincronizado em tempo real com a origem antes do corte definitivo.
Como preservar o encoding UTF-8 ao migrar PostgreSQL entre servidores?
Ao criar o banco de destino, especifique explicitamente o encoding com CREATE DATABASE nome ENCODING 'UTF8' LC_COLLATE 'pt_BR.UTF-8' LC_CTYPE 'pt_BR.UTF-8'. O pg_dump exporta os dados em texto puro e o pg_restore os importa respeitando o encoding do banco de destino. Certifique-se também de que o locale pt_BR.UTF-8 está instalado no sistema operacional do servidor de destino antes de criar o banco.
Qual a diferença entre pg_dump e pg_dumpall para migração?
O pg_dump exporta um único banco de dados, enquanto o pg_dumpall exporta todos os bancos do cluster PostgreSQL, incluindo roles globais e tablespaces. Para migrar um banco específico, use pg_dump. Para migrar toda a instância, use pg_dumpall. Em migrações parciais, a prática recomendada é combinar pg_dump para os dados com pg_dumpall --roles-only para os roles.
Como verificar se a migração do PostgreSQL foi bem-sucedida?
Após o restore, conecte ao banco de destino com psql e execute SELECT count(*) FROM nome_da_tabela para comparar o número de registros com o banco de origem. Também verifique a integridade com \dt para listar tabelas e \du para confirmar os roles migrados. Verifique ainda as sequências de auto-incremento, que podem precisar de ajuste manual após a restauração.
Posso migrar PostgreSQL entre versões diferentes, como da 14 para a 16?
Sim, o método pg_dump/pg_restore é compatível entre versões diferentes do PostgreSQL. O dump gerado na versão 14 pode ser restaurado na versão 16 sem problemas. Para migrações entre versões maiores, o pg_upgrade é uma alternativa mais rápida, mas exige que ambas as versões estejam instaladas no mesmo servidor e que o cluster seja parado durante o processo.
Conclusão
Migrar um banco de dados PostgreSQL pela linha de comando é um processo confiável e reproduzível quando executado com os passos corretos. Os pontos mais importantes para garantir o sucesso da migração são:
- Exporte com pg_dump -Fc para obter um dump comprimido e compatível com restauração paralela, e sempre migre os roles separadamente com
pg_dumpall --roles-onlyantes de restaurar os dados. - Crie o banco de destino com encoding e locale explícitos (
UTF8ept_BR.UTF-8) usandoTEMPLATE template0para evitar erros de incompatibilidade de locale. - Valide a integridade após a restauração comparando contagem de registros, listando tabelas com
\dte verificando sequências antes de apontar sua aplicação para o novo servidor.
Leia também
- Migrar banco de dados MySQL entre servidores Linux sem perda
- Passo a passo para transferir PostgreSQL entre servidores preservando encoding
- Guia: Laravel não conecta ao MySQL no Debian 12
Precisa de ajuda com migração de banco de dados PostgreSQL?
Configurar e migrar bancos de dados em servidores Linux exige atenção a detalhes de encoding, permissões e conectividade. Os planos de VPS da AviraHost oferecem acesso root completo, suporte técnico especializado e infraestrutura estável para hospedar suas aplicações com PostgreSQL sem complicações.