---
title: "Backup do PostgreSQL com pg_dump e cron: script, rotação e restauração"
description: "Faça backup diário do PostgreSQL com pg_dump em formato custom, agende no cron, apague cópias antigas, copie para fora da VPS e teste a restauração."
url: "https://streethosting.com.br/guias/vps/backup-postgresql-pg-dump-cron"
category: "vps"
slug: "backup-postgresql-pg-dump-cron"
datePublished: "2026-11-13"
dateModified: "2026-11-13"
author: "Equipe StreetHosting"
difficulty: "intermediario"
language: "pt-BR"
keywords:
  - "backup postgresql pg_dump"
  - "pg_dump cron"
  - "pg_restore restaurar backup"
  - "pg_dumpall papéis"
  - "backup postgresql docker"
  - "pgpass senha automática"
---

# Backup do PostgreSQL com pg_dump e cron, e como restaurar de verdade

Um backup só vale se você consegue restaurar. Veja como gerar dumps do PostgreSQL com pg_dump, guardar papéis e globais com pg_dumpall, automatizar com cron, girar as cópias antigas, levar para fora da VPS e testar a restauração.

> **Resposta rápida**
>
> Gere o backup com `pg_dump -Fc -f arquivo.dump nome_do_banco`, guarde papéis e globais com `pg_dumpall --globals-only` e restaure com `pg_restore --clean --if-exists -d nome_do_banco arquivo.dump`. Automatize com um script que põe a data no nome, rode no cron como o usuário postgres (ou com um arquivo .pgpass de permissão 600), apague o que passar de N dias e copie para fora da VPS. O passo que quase ninguém faz e o mais importante: restaurar de verdade num banco de teste.

## pg_dump, pg_dumpall e os formatos

O PostgreSQL traz duas ferramentas de backup lógico. O `pg_dump` exporta **um banco**: tabelas, dados, índices, funções. O `pg_dumpall` exporta o **servidor inteiro**, e a parte que interessa nele é a dos papéis (usuários e grupos) e dos objetos globais, que o pg_dump deixa de fora. Sem os papéis, uma restauração num servidor novo dá erro ao tentar dar posse de tabelas a um usuário que não existe.

O pg_dump escolhe o formato pela opção `-F`:

- **custom (-Fc):** arquivo comprimido e binário. Restaura com pg_restore, permite escolher o que voltar (uma tabela, um esquema) e aceita restauração em paralelo. É o que recomendamos.
- **texto (padrão):** um arquivo SQL puro. Dá para ler e editar, mas é maior e se restaura inteiro com o psql.
- **diretório (-Fd):** uma pasta com um arquivo por tabela, útil para bancos grandes porque permite o dump em paralelo.

Esses comandos fazem backup lógico: exportam o conteúdo como instruções. Não substituem a cópia dos arquivos do disco de uma só vez nem o arquivamento contínuo de WAL, que permite voltar a um minuto exato. Para a maioria dos sites e aplicações pequenas, um dump diário resolve. Se instalar o banco agora, o [guia de PostgreSQL no Ubuntu](https://streethosting.com.br/guias/vps/instalar-postgresql-vps-ubuntu) mostra o começo.

## O primeiro backup e a primeira restauração

Antes de automatizar, rode na mão para ver funcionar. Como o usuário postgres, que tem acesso local sem senha por padrão no Ubuntu:

```
sudo -u postgres pg_dump -Fc -f /tmp/meubanco.dump meubanco
sudo -u postgres pg_dumpall --globals-only -f /tmp/globals.sql
ls -lh /tmp/meubanco.dump /tmp/globals.sql
```

Para restaurar num banco novo, crie o banco vazio e aponte o pg_restore para ele:

```
# 1) papéis primeiro, só se o servidor for novo
sudo -u postgres psql -f /tmp/globals.sql

# 2) banco vazio e restauração
sudo -u postgres createdb meubanco_teste
sudo -u postgres pg_restore -d meubanco_teste /tmp/meubanco.dump
```

Para sobrescrever um banco que já existe com o conteúdo do dump, use `--clean`, que apaga cada objeto antes de criar de novo, junto de `--if-exists`, que evita erro quando o objeto ainda não existe:

```
sudo -u postgres pg_restore --clean --if-exists -d meubanco /tmp/meubanco.dump
```

> **Atenção**
>
> O `--clean` destrói os dados atuais do banco indicado. Rode num banco de teste primeiro e só aponte para a produção quando tiver certeza de que o dump é o certo e de que a aplicação está parada.

## Script com data no nome

O script abaixo faz tudo de uma vez: dump do banco, dump dos globais, validação do arquivo e limpeza dos antigos. Ele grava primeiro num nome temporário e só renomeia no fim, para que um backup incompleto nunca pareça um backup bom. Salve em `/usr/local/bin/backup-postgres.sh`:

```
#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/var/backups/postgres"
BANCO="meubanco"
DIAS=14
DATA="$(date +%F_%H%M)"

mkdir -p "$BACKUP_DIR"

# dump do banco em formato custom, com nome temporário
pg_dump -Fc -f "$BACKUP_DIR/${BANCO}_${DATA}.dump.tmp" "$BANCO"

# o arquivo precisa ser legível pelo pg_restore
pg_restore --list "$BACKUP_DIR/${BANCO}_${DATA}.dump.tmp" > /dev/null
mv "$BACKUP_DIR/${BANCO}_${DATA}.dump.tmp" "$BACKUP_DIR/${BANCO}_${DATA}.dump"

# papéis e objetos globais
pg_dumpall --globals-only -f "$BACKUP_DIR/globals_${DATA}.sql"

# rotação: apaga o que tem mais de N dias
find "$BACKUP_DIR" -type f \( -name "*.dump" -o -name "globals_*.sql" \) -mtime +"$DIAS" -delete

echo "backup ok: ${BANCO}_${DATA}.dump"
```

Prepare o diretório e dê permissão de execução. Como o script vai rodar como postgres, o diretório precisa ser dele:

```
sudo mkdir -p /var/backups/postgres
sudo chown postgres:postgres /var/backups/postgres
sudo chmod 700 /var/backups/postgres
sudo chmod +x /usr/local/bin/backup-postgres.sh
sudo -u postgres /usr/local/bin/backup-postgres.sh
```

> **Dica**
>
> O `set -euo pipefail` faz o script parar no primeiro erro. Se o pg_dump falhar, nada é renomeado e nada antigo é apagado, o que protege você de uma rotação que apaga todos os backups bons depois de uma semana de falhas silenciosas.

## Rodar sem senha: usuário postgres ou .pgpass

Um script agendado não pode parar para pedir senha. Há dois caminhos. O mais simples é rodar como o usuário de sistema `postgres`, que conecta pelo socket local sem senha. É o que o exemplo acima faz.

O segundo é rodar como outro usuário, ou conectar a um servidor remoto, com um arquivo **.pgpass** na pasta pessoal. Cada linha segue o formato `servidor:porta:banco:usuario:senha`, e o PostgreSQL ignora o arquivo se a permissão for mais aberta do que 600:

```
echo "127.0.0.1:5432:meubanco:backup:SENHA_AQUI" >> ~/.pgpass
chmod 600 ~/.pgpass

# o pg_dump precisa dizer servidor e usuário, para casar com a linha
pg_dump -h 127.0.0.1 -U backup -Fc -f /tmp/teste.dump meubanco
```

Crie um papel só para backup, com permissão de leitura, em vez de usar o superusuário. Evite pôr a senha na linha de comando, porque ela aparece na lista de processos e no histórico do shell. A variável PGPASSWORD também não é recomendada pela documentação do PostgreSQL, já que alguns sistemas deixam outros usuários lerem o ambiente de um processo.

## Cron diário e rotação

Edite o cron do usuário postgres e agende o script para uma hora de pouco movimento. O formato do cron e as armadilhas de ambiente estão no [guia de cron na VPS](https://streethosting.com.br/guias/vps/configurar-cron-tarefas-agendadas-vps).

```
sudo -u postgres crontab -e

# todo dia às 3h15, com registro em arquivo
15 3 * * * /usr/local/bin/backup-postgres.sh >> /var/backups/postgres/backup.log 2>&1
```

A rotação já está no script, na linha do `find ... -mtime +14 -delete`. Escolha o número de dias pelo espaço que você tem e por quanto tempo precisa voltar no passado: 14 dias é um começo razoável. Calcule o espaço: o tamanho de um dump vezes o número de dias. O [guia de espaço em disco](https://streethosting.com.br/guias/vps/descobrir-o-que-ocupa-espaco-vps) ajuda a acompanhar isso.

> **Atenção**
>
> Cuidado com o comando de rotação. Teste primeiro trocando `-delete` por `-print` para ver quais arquivos seriam apagados, e confirme que o caminho aponta só para a pasta de backup.

## Banco dentro do Docker

Se o PostgreSQL roda em um contêiner, o pg_dump do próprio contêiner faz o trabalho e você redireciona a saída para um arquivo no host. Um detalhe que estraga backups: **não use a opção -t** do `docker exec`. Ela cria um terminal que converte quebras de linha e corrompe o arquivo binário do formato custom.

```
# backup (sem -t)
docker exec postgres pg_dump -U meuusuario -Fc meubanco > /var/backups/postgres/meubanco_$(date +%F).dump

# papéis e globais
docker exec postgres pg_dumpall -U meuusuario --globals-only > /var/backups/postgres/globals_$(date +%F).sql

# restauração: use -i para enviar o arquivo pela entrada padrão
docker exec -i postgres pg_restore -U meuusuario -d meubanco --clean --if-exists < /var/backups/postgres/meubanco_2026-11-13.dump
```

Troque `postgres` pelo nome do seu contêiner (veja em `docker ps`) e `meuusuario` pelo usuário do banco. No cron, use o caminho completo do docker e rode como um usuário que tenha acesso a ele. Lembre que o volume de dados do contêiner não é backup: se o volume sumir, o banco some junto. A estrutura do Compose está no [guia de Docker Compose](https://streethosting.com.br/guias/vps/docker-compose-vps-guia).

## Levar para fora da VPS

Um backup guardado só no mesmo disco do banco protege contra erro de comando, mas não contra falha do disco, do servidor ou da conta. A regra é ter cópia em outro lugar. A estratégia completa, com número de cópias e tipos de mídia, está no guia da [estratégia de backup 3-2-1](https://streethosting.com.br/guias/infraestrutura/estrategia-backup-3-2-1-servidor).

Na prática, adicione ao script (ou ao cron) um envio para outro servidor ou para um armazenamento de objetos. Com rsync por SSH fica assim:

```
rsync -a --delete-after /var/backups/postgres/ backup@OUTRO_SERVIDOR:/backups/vps1/postgres/
```

Se preferir uma ferramenta que cifra, deduplica e guarda histórico, o [guia de backup com restic e cron](https://streethosting.com.br/guias/vps/automatizar-backup-vps-restic-cron) mostra como incluir a pasta dos dumps nele. Os dumps contêm todos os dados do banco, inclusive os sensíveis, então cifre antes de mandar para um lugar que você não controla.

## Testar a restauração de verdade

Um arquivo de backup que ninguém nunca restaurou é uma esperança, não um backup. Reserve um tempo, no começo e depois a cada poucos meses, para este roteiro, num banco de teste e nunca em produção:

1. Pegue o dump mais recente, de preferência a cópia que está fora da VPS, para testar também o caminho de volta.
2. Crie um banco vazio com `createdb meubanco_teste`.
3. Restaure com `pg_restore -d meubanco_teste arquivo.dump` e leia os erros, se houver.
4. Compare com a produção: número de tabelas e contagem de linhas das tabelas principais, com `SELECT count(*)`.
5. Se possível, aponte uma cópia da aplicação para o banco de teste e confira que ela sobe e lê os dados.
6. Anote quanto tempo levou. Esse é o seu tempo real de recuperação num dia ruim.
7. Apague o banco de teste com `dropdb meubanco_teste`.

Junte a isso um aviso quando o backup falhar. O arquivo de log do cron ajuda, mas ninguém lê log até precisar. Um alerta simples quando o script termina com erro evita descobrir na hora errada que o backup parou há um mês.

## Onde rodar isso na StreetHosting

Nas VPS da StreetHosting você tem acesso root, virtualização KVM e disco NVMe, em São Paulo. Isso dá liberdade para instalar o PostgreSQL, os clientes de backup e o cron do jeito que este guia descreve, e deixa o dump e a restauração rápidos. Guardar os dumps dos últimos dias no mesmo servidor é só uma das cópias: a que importa na hora do desastre é a que está em outro lugar. A ativação é automática em cerca de 60 segundos depois do pagamento por Pix ou cartão.

## Perguntas frequentes

### Qual formato de pg_dump devo usar?

Para backup de produção, o formato custom (opção -Fc). Ele é comprimido, permite restaurar só uma tabela ou um esquema com pg_restore e aceita restauração em paralelo com a opção -j. O formato texto (SQL puro) é legível, mas é maior e a restauração é mais limitada.

### O pg_dump trava o banco enquanto roda?

Não. O pg_dump tira uma fotografia consistente do banco usando uma transação e não bloqueia leituras nem escritas das outras conexões. Só mudanças de estrutura, como ALTER TABLE, esperam ele terminar. Ele consome CPU e disco enquanto trabalha, então agende em horário de pouco movimento se o banco for grande.

### O pg_dump salva usuários e senhas?

Não. O pg_dump guarda um banco por vez e não leva os papéis (usuários) nem os objetos globais do servidor. Para isso use o pg_dumpall com a opção --globals-only e guarde o arquivo junto dos dumps dos bancos.

### Com que frequência devo fazer o backup?

Depende de quanto dado você aceita perder. Um dump diário significa que, no pior caso, você perde até 24 horas. Se isso é demais, rode de hora em hora ou estude arquivamento contínuo de WAL, que é um assunto à parte. Em qualquer caso, mantenha cópia fora da VPS.

### Como saber se o backup está bom?

Só restaurando. O comando pg_restore --list mostra se o arquivo é legível, mas o teste de verdade é criar um banco vazio, restaurar o dump nele e conferir se as tabelas e a contagem de linhas batem com a produção. Faça isso periodicamente.

## Guias relacionados

- [Como instalar PostgreSQL na VPS Ubuntu com segurança](https://streethosting.com.br/guias/vps/instalar-postgresql-vps-ubuntu.md)
- [Como configurar backup automático da VPS com restic e cron](https://streethosting.com.br/guias/vps/automatizar-backup-vps-restic-cron.md)
- [Estratégia de backup 3 2 1 para servidores](https://streethosting.com.br/guias/infraestrutura/estrategia-backup-3-2-1-servidor.md)
- [Como agendar tarefas na VPS com cron](https://streethosting.com.br/guias/vps/configurar-cron-tarefas-agendadas-vps.md)
- [Docker Compose na VPS: aplicação e banco de dados em um compose.yaml](https://streethosting.com.br/guias/vps/docker-compose-vps-guia.md)

## Produtos citados

- https://streethosting.com.br/vps

## Dados estruturados

```json
[
  {
    "@context": "https://schema.org",
    "@type": [
      "Article",
      "TechArticle"
    ],
    "headline": "Backup do PostgreSQL com pg_dump e cron, e como restaurar de verdade",
    "name": "Backup do PostgreSQL com pg_dump e cron: script, rotação e restauração",
    "abstract": "Um backup só vale se você consegue restaurar. Veja como gerar dumps do PostgreSQL com pg_dump, guardar papéis e globais com pg_dumpall, automatizar com cron, girar as cópias antigas, levar para fora da VPS e testar a restauração.",
    "description": "Faça backup diário do PostgreSQL com pg_dump em formato custom, agende no cron, apague cópias antigas, copie para fora da VPS e teste a restauração.",
    "datePublished": "2026-11-13",
    "dateModified": "2026-11-13",
    "author": {
      "@type": "Organization",
      "name": "Equipe StreetHosting"
    },
    "publisher": {
      "@type": "Organization",
      "name": "StreetHosting",
      "url": "https://streethosting.com.br"
    },
    "inLanguage": "pt-BR",
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://streethosting.com.br/guias/vps/backup-postgresql-pg-dump-cron"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "Qual formato de pg_dump devo usar?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Para backup de produção, o formato custom (opção -Fc). Ele é comprimido, permite restaurar só uma tabela ou um esquema com pg_restore e aceita restauração em paralelo com a opção -j. O formato texto (SQL puro) é legível, mas é maior e a restauração é mais limitada."
        }
      },
      {
        "@type": "Question",
        "name": "O pg_dump trava o banco enquanto roda?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Não. O pg_dump tira uma fotografia consistente do banco usando uma transação e não bloqueia leituras nem escritas das outras conexões. Só mudanças de estrutura, como ALTER TABLE, esperam ele terminar. Ele consome CPU e disco enquanto trabalha, então agende em horário de pouco movimento se o banco for grande."
        }
      },
      {
        "@type": "Question",
        "name": "O pg_dump salva usuários e senhas?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Não. O pg_dump guarda um banco por vez e não leva os papéis (usuários) nem os objetos globais do servidor. Para isso use o pg_dumpall com a opção --globals-only e guarde o arquivo junto dos dumps dos bancos."
        }
      },
      {
        "@type": "Question",
        "name": "Com que frequência devo fazer o backup?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Depende de quanto dado você aceita perder. Um dump diário significa que, no pior caso, você perde até 24 horas. Se isso é demais, rode de hora em hora ou estude arquivamento contínuo de WAL, que é um assunto à parte. Em qualquer caso, mantenha cópia fora da VPS."
        }
      },
      {
        "@type": "Question",
        "name": "Como saber se o backup está bom?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Só restaurando. O comando pg_restore --list mostra se o arquivo é legível, mas o teste de verdade é criar um banco vazio, restaurar o dump nele e conferir se as tabelas e a contagem de linhas batem com a produção. Faça isso periodicamente."
        }
      }
    ]
  }
]
```
