Backup PostgreSQL com PITR ao segundo. pg_basebackup nativo + arquivamento WAL contínuo, sem janela de manutenção, restauração ponto-no-tempo precisa em sub-minuto.
- Base backup quente via pg_basebackup — sem bloquear escrita.
- WAL archiving contínuo — RPO próximo de zero, recovery ao segundo exato.
- Compatível 9.6 → 16+ — mesmo plugin para todas as versões em produção.
- Streaming replication integration — backup pode rodar do standby, zero overhead no primário.
- Validação automática — pg_verifybackup pós-job, alerta se algo divergir.
Comece em 30 dias, no mínimo 50% mais barato. Trial gratuito, RPMs e DEBs assinados, suporte direto com Heitor Faria. Substitua sua licença Veeam, Commvault ou Bacula Enterprise sem quebrar a janela noturna.
Solicitar trial gratuito de 30 dias →
💰 Oferta Comercial Especial
“Traga sua proposta de contratação ou renovação do Bacula Enterprise, Veeam, Commvault ou Netbackup. Damos no mínimo 50% de desconto, com muito mais funcionalidades.”
“Traga-nos sua proposta de contrato ou renovação do Bacula Enterprise, Veeam, Commvault ou Netbackup. Oferecemos no mínimo 50% de desconto — e significativamente mais recursos.”
Contato — Heitor Faria 📧 heitor@opentechs.lat 📞 +1 (786) 726-1749 💬 +55 (61) 98268-4220 (WhatsApp)
Índice
- Sumário Executivo
- Por Que Este Plugin Existe
- Casos de Uso
- Visão Geral da Arquitetura
- Comparação de Recursos vs. Alternativas Comerciais
- Requisitos de Sistema e Compatibilidade
- Dimensionamento Recomendado
- Procedimento de Instalação
- Manual de Configuração
- Parâmetros de Backup — Referência Completa
- Parâmetros de Restauração — Referência Completa
- Exemplos de FileSet e Job
- Captura de Replicação e Failover
- Fluxo de Restauração Automatizada
- Prova de Funcionalidade — Screenshots e Logs Reais
- Segurança e Assinatura
- Licenciamento
- Suporte e Contratação Comercial
1. Sumário Executivo
PodHeitor PostgreSQL Backup and Replication Plugin for Bacula é um metaplugin de nível produção que transforma o PodHeitor Backup Edition (gratuito, código aberto) em uma plataforma completa de proteção de dados PostgreSQL que iguala ou supera o conjunto de recursos de produtos de backup comerciais premium — a uma fração do custo total de propriedade.
Ele preenche a lacuna mais importante no stack Bacula de código aberto: integração nativa com PostgreSQL, com suporte a metaplugin, incluindo incremental em nível de bloco, Point-In-Time Recovery (PITR), Proteção Contínua de Dados (CDP), e captura de topologia de replicação — recursos que, até agora, exigiam licenciamento proprietário do Bacula Enterprise ou ferramentas pesadas de terceiros como Veeam, Commvault ou Veritas NetBackup.
Principais Diferenciais
| Capacidade | PodHeitor (este plugin) | Bacula Enterprise | Veeam / Commvault / NB |
|---|---|---|---|
| Executa no Bacula Community | ✅ | ❌ (apenas enterprise) | N/A |
| PITR (baseado em WAL) | ✅ | ✅ | ✅ |
Incremental em nível de bloco (PG 17 pg_combinebackup) |
✅ | ⚠️ parcial | ❌ |
| Captura de topologia de replicação + recriação automática | ✅ | ❌ | ❌ |
| Backup apenas do standby (descarga do primário) | ✅ | ✅ | ⚠️ |
| Modo de Proteção Contínua de Dados (CDP) | ✅ | ❌ | ⚠️ |
| Binários totalmente assinados (GPG RSA-4096) | ✅ | ✅ | ✅ |
| Restauração automatizada com um comando | ✅ | ❌ | ⚠️ |
| Custo de licenciamento (por FD / por TB) | US$ 0 – valor fixo baixo | US$ $$$ | US$ $$$$ |
Números-Chave
- 5 modos de backup:
dump,parallel_dump,pitr,pitr_block,cdp - 115 testes unitários + validação E2E contra cluster PostgreSQL 17 real
- Testado em: PostgreSQL 12 → 17, CentOS 7 → RHEL 9, Debian 11/12, Oracle Linux 9.6
- Linha de base glibc-2.17 — um único binário RPM que executa em todos
os Linux enterprise convencionais a partir de 2014
- Releases com dupla assinatura: chave RSA-4096
E8E2744FF20A4E2408920E33104B2B720DC8DBEF
2. Por Que Este Plugin Existe
O PodHeitor Backup Edition é o sistema de backup empresarial de código aberto mais amplamente implantado no mundo. Ele protege Linux, Windows, VMs, armazenamento em objeto, fita — tudo, exceto bancos de dados, de forma nativa.
A arquitetura oficial de metaplugin existe no Community Edition, mas as integrações com bancos de dados são fornecidas apenas com a assinatura paga do Bacula Enterprise. Isso força os usuários de código aberto a uma de três alternativas insatisfatórias:
- Pagar pelo Bacula Enterprise — começa na casa de dezenas de milhares
de US$ por ano para um ambiente de porte médio.
- Desenvolver a própria solução — scripts frágeis, sem PITR,
sem modo Accurate, sem streaming a partir do File Daemon.
- Adotar uma segunda ferramenta (Veeam, Commvault, NetBackup) — infraestrutura
duplicada, licenciamento duplicado, carga operacional duplicada.
PodHeitor fecha essa lacuna. É um metaplugin desenvolvido do zero que integra-se nativamente com a arquitetura de metaplugin do PodHeitor Backup, de modo que todos os recursos do PodHeitor Backup — modo Accurate, agendamento Differential/Incremental, criptografia, deduplicação, bibliotecas de fita, armazenamento em nuvem — simplesmente funcionam, sem modificações.
3. Casos de Uso
3.1 Banco de dados único — PME / mercado intermediário
“Já usamos o PodHeitor Backup para nossos arquivos e VMs. Precisamos de backups do PostgreSQL com PITR. Não queremos pagar pelo Bacula Enterprise.”
→ Instale o RPM/DEB, adicione uma linha Plugin ao seu FileSet e agende. Pronto em 15 minutos. Zero infraestrutura duplicada.
3.2 Grande ambiente PostgreSQL com streaming replication
“Temos 20 clusters PostgreSQL, cada um com 1–3 standbys. Precisamos de incremental em nível de bloco e precisamos reconstruir a topologia de replicação após uma restauração de DR.”
→ Modo pitr_block + track_replication_state = true. O plugin captura pg_replication_slots, pg_subscription, e o standby_signal / postgresql.auto.conf de cada standby. Na restauração, ele regenera os arquivos SQL e de configuração para que a topologia seja restabelecida integralmente.
3.3 Setores regulados (financeiro, saúde, governo)
“Precisamos de PITR ao segundo, cadeia de custódia auditável na mídia de backup e binários assinados.”
→ O modo PITR grava segmentos WAL em volumes gerenciados pelo Bacula com integridade criptográfica (assinatura de bloco SHA-256 nativa do Bacula). Os binários do plugin são assinados com GPG usando uma chave RSA de 4.096 bits publicada em uma URL conhecida.
3.4 Troca de renovação — cenário comercial
“Nossa renovação do Bacula Enterprise / Veeam / Commvault / NetBackup chegou na casa de seis dígitos. O que vocês podem oferecer?”
→ Veja o aviso no topo deste documento. No mínimo 50% de desconto, com mais recursos. Traga-nos a proposta.
4. Visão Geral da Arquitetura
┌──────────────┐ ┌──────────────┐ ┌───────────────┐
│ Director │────────▶│ File Daemon │◀───────▶│ Storage Daemon│
│ (bacula-dir) │ jobs │ (bacula-fd) │ data │ (bacula-sd) │
└──────────────┘ └──────┬───────┘ └───────────────┘
│
│ metaplugin API (C/C++)
▼
┌──────────────────────────────┐
│ podheitor-postgresql-fd.so │ Proprietary
│ (plugin bridge) │
└──────────────┬───────────────┘
│ fork + pipes (stdin/stdout)
│ binary framed protocol
▼
┌──────────────────────────────┐
│ podheitor-postgresql-backend │ Proprietary (Rust)
│ - backup orchestrator │
│ - psql session manager │
│ - WAL / block-level logic │
│ - replication capture │
└──────────────┬───────────────┘
│ libpq / psql
▼
┌──────────────────┐
│ PostgreSQL │
│ 12 / 13 / 14 / │
│ 15 / 16 / 17 │
└──────────────────┘
Divisão de Componentes
| Componente | Linguagem | Licença | Função |
|---|---|---|---|
podheitor-postgresql-fd.so |
Rust | PodHeitor-Proprietary | Plugin loader do Bacula FD — traduz callbacks em chamadas para o backend |
podheitor-postgresql-backend |
Rust | Proprietária | Toda a lógica PostgreSQL: backup, restauração, replicação, WAL, PITR |
podheitor-postgresql.conf |
texto | N/A | Conexão, papel, credenciais, opções |
A arquitetura dual-process é intencional: o plugin loader é mínimo; a propriedade intelectual reside no backend Rust proprietário, que executa como subprocesso isolado comunicando-se via protocolo binário interno.
5. Comparação de Recursos vs. Alternativas Comerciais
| Recurso | PodHeitor v1.3 | Bacula Enterprise 18 | Veeam B&R 12 | Commvault 11 | Veritas NetBackup 10 |
|---|---|---|---|---|---|
| Executa no PodHeitor Backup (gratuito) | ✅ | ❌ | ❌ | ❌ | ❌ |
| Integração nativa como metaplugin do Bacula | ✅ | ✅ | N/A | N/A | N/A |
DUMP (pg_dump) |
✅ | ✅ | ✅ | ✅ | ✅ |
DUMP paralelo (-j) |
✅ | ✅ | ⚠️ | ⚠️ | ⚠️ |
| PITR — completo/diferencial/incremental | ✅ | ✅ | ✅ | ✅ | ✅ |
| Incremental em nível de bloco (PG 17) | ✅ | ⚠️ | ❌ | ❌ | ❌ |
| Modo CDP | ✅ | ❌ | ⚠️ | ⚠️ | ❌ |
| Backup apenas do standby | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ |
| Captura de topologia de replicação | ✅ | ❌ | ❌ | ❌ | ❌ |
| Restauração automatizada em 6 fases | ✅ | ❌ | ⚠️ | ✅ | ⚠️ |
| Funciona com o modo Accurate do Bacula | ✅ | ✅ | N/A | N/A | N/A |
| Binários assinados com GPG | ✅ | ✅ | ✅ | ✅ | ✅ |
| Custo: 1 FD + 500 GB PG (tabela, 1 ano) | negociado — até 50% de desconto sobre a proposta deles | ~US$ 15.000 | ~US$ 12.000 | ~US$ 20.000 | ~US$ 18.000 |
Legenda: ✅ suporte nativo completo | ⚠️ parcial/via script/licenciamento adicional | ❌ não suportado
6. Requisitos de Sistema e Compatibilidade
Versões suportadas do PostgreSQL
| Versão | DUMP | DUMP Paralelo | PITR | PITR_BLOCK | CDP | Captura de replicação |
|---|---|---|---|---|---|---|
| 12 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| 13 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| 14 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| 15 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| 16 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| 17 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
pitr_block requer o utilitário pg_combinebackup do PostgreSQL 17; os demais modos funcionam a partir do PG 12.
Versões suportadas do Bacula
| Distribuição Bacula | Versão mínima | Testado |
|---|---|---|
| Bacula Community (upstream, gratuito) | 15.0.0 | 15.0.3 |
| Bacula Enterprise | 18.0.0 | 18.0.x |
| Bacula Community (LTS anterior) | 13.0.x | caso a caso, entre em contato |
Distribuições Linux suportadas (para o host do plugin / File Daemon)
| Distribuição | Pacote | glibc | Testado |
|---|---|---|---|
| RHEL 7 / CentOS 7 | .el7.x86_64.rpm |
2.17 | ✅ |
| RHEL 8 / Rocky 8 / Alma 8 | .el9.x86_64.rpm |
2.28 | ✅ |
| RHEL 9 / Oracle Linux 9 / Rocky 9 / Alma 9 | .el9.x86_64.rpm |
2.34 | ✅ |
| Debian 11 (Bullseye) | _amd64.deb |
2.31 | ✅ |
| Debian 12 (Bookworm) | _amd64.deb |
2.36 | ✅ |
| Ubuntu 20.04 LTS | _amd64.deb |
2.31 | ✅ |
| Ubuntu 22.04 LTS | _amd64.deb |
2.35 | ✅ |
| Ubuntu 24.04 LTS | _amd64.deb |
2.39 | ✅ |
Qualquer glibc ≥ 2.17 (sem .deb/.rpm) |
*.musl.tar.gz |
estático | ✅ |
Arquitetura: somente x86_64 na v1.3. ARM64 está no roadmap da v2.0.
Outros requisitos
| Requisito | Detalhe |
|---|---|
postgresql-client ≥ 14 |
psql, pg_dump, pg_restore, pg_basebackup, pg_combinebackup (PG 17) no host do plugin |
| Conectividade de rede | Host do plugin → PostgreSQL (TCP, padrão 5432) + File Daemon ↔ Storage Daemon |
| Credenciais | Um papel PG com REPLICATION, pg_read_all_data e (para captura de replicação) pg_read_all_settings |
| Disco (host do plugin, armazenamento temporário) | 1× tamanho do maior cluster de banco de dados durante pitr_block (opcional; transmitido caso contrário) |
7. Dimensionamento Recomendado
Host do plugin (tipicamente = host do File Daemon)
| Métrica | Pequeno (<100 GB PG) | Médio (100 GB – 1 TB) | Grande (1 – 10 TB) | XL (> 10 TB) |
|---|---|---|---|---|
| Núcleos de CPU | 2 | 4 | 8 | 16+ |
| RAM | 2 GB | 4 GB | 8 GB | 16 GB+ |
| Disco (armazenamento temporário) | 10 GB | 50 GB | 200 GB | 500 GB+ |
| Rede (para PG) | 1 GbE | 1 GbE | 10 GbE | 10 GbE+ |
| Rede (para SD) | 1 GbE | 10 GbE | 10 GbE | 25 GbE+ |
Servidor PostgreSQL (sem dimensionamento extra além da operação normal)
max_wal_senders≥ 2 (um para o plugin, um para os standbys existentes)wal_level = replica(oulogicalse você usa logical replication)archive_mode = onnão é obrigatório — o plugin usapg_backup_start/stop+ streaming WAL direto; mas também suportamos configurações com archive-mode.- Para
pitr_block:summarize_wal = on(PG 17+)
Storage Daemon do Bacula
Dimensione como faria para qualquer carga de trabalho de backup de volume equivalente. O plugin emite streams padrão do Bacula, portanto as diretrizes de dimensionamento existentes do SD se aplicam integralmente — sem overhead específico do plugin.
8. Procedimento de Instalação
8.1 Verificar assinaturas (recomendado)
Baixe a chave pública uma vez:
Em seguida, verifique cada artefato:
gpg --verify podheitor-postgresql-plugin-1.3.0-1.el9.x86_64.rpm.asc
podheitor-postgresql-plugin-1.3.0-1.el9.x86_64.rpm
# expected: Good signature from "Heitor Faria <heitor@opentechs.lat>"
8.2 Instalação via RPM (RHEL 7 / 8 / 9, Oracle Linux, Rocky, Alma)
RHEL 9 / Oracle Linux 9 / Rocky 9 / Alma 9:
sudo dnf install -y postgresql-client
sudo rpm --import podheitor-release.pub
sudo rpm -Uvh podheitor-postgresql-plugin-1.3.0-1.el9.x86_64.rpm
RHEL 7 / CentOS 7:
sudo yum install -y postgresql
sudo rpm --import podheitor-release.pub
sudo rpm -Uvh podheitor-postgresql-plugin-1.3.0-1.el7.x86_64.rpm
8.3 Instalação via DEB (Debian 11/12, Ubuntu 20.04+)
sudo apt update && sudo apt install -y postgresql-client
sudo dpkg -i podheitor-postgresql-plugin_1.3.0-1_amd64.deb
8.4 Tarball musl estático (qualquer glibc ≥ 2.17)
tar -xzf podheitor-postgresql-backend-1.3.0-musl-x86_64.tar.gz -C /opt/bacula/bin/
# then install the .so and config manually
<h3>8.5 Arquivos instalados pelo pacote</h3>
<pre><code>/opt/bacula/plugins/podheitor-postgresql-fd.so ← the metaplugin .so
/opt/bacula/bin/podheitor-postgresql-backend ← Rust backend binary
/opt/bacula/sbin/podheitor-postgresql-backend ← symlink (Bacula source builds)
/opt/bacula/etc/podheitor-postgresql.conf ← example config (0640 root:bacula)
/opt/bacula/etc/podheitor-postgresql/LICENSE ← proprietary
/opt/bacula/etc/podheitor-postgresql/NOTICE ← attributions
8.6 Teste básico pós-instalação
/opt/bacula/bin/podheitor-postgresql-backend --version
# expected: podheitor-postgresql-backend 1.3.0
9. Manual de Configuração
9.1 Configuração do File Daemon
Adicione ao /opt/bacula/etc/bacula-fd.conf (ou ao equivalente em configuração dividida):
FileDaemon {
Name = backup-server-fd
Plugin Directory = /opt/bacula/plugins
Plugin Names = "podheitor-postgresql-fd"
# ... existing options ...
}
Em seguida, recarregue:
sudo systemctl reload bacula-fd
9.2 Configuração de conexão do plugin
Edite /opt/bacula/etc/podheitor-postgresql.conf:
[connection]
host = localhost
port = 5432
user = bacula_backup
password = <strong-password>
# alternatively:
# pgpass_file = /root/.pgpass
[options]
# Force backups to run from standby (protect primary from load)
backup_from_standby = false
# Capture replication slots + subscriptions for automated topology restore
track_replication_state = true
# Parallel jobs for parallel_dump mode
parallel_jobs = 4
# Temp directory for pitr_block staging
tmpdir = /var/tmp/podheitor
9.3 Papel PostgreSQL recomendado
CREATE ROLE bacula_backup WITH LOGIN REPLICATION PASSWORD '...';
GRANT pg_read_all_data, pg_read_all_settings TO bacula_backup;
10. Parâmetros de Backup — Referência Completa
Passados via diretiva Plugin do FileSet:
Plugin = "podheitor-postgresql: mode=<mode> <param>=<value> ..."
| Parâmetro | Tipo | Padrão | Valores | Descrição |
|---|---|---|---|---|
mode |
string | dump |
dump, parallel_dump, pitr, pitr_block, cdp |
Estratégia de backup |
database |
string | * (todos) |
nome do banco ou lista separada por vírgula | Qual(is) banco(s) fazer backup |
parallel_jobs |
int | 4 |
1–64 | -j para parallel_dump |
dump_format |
string | custom |
custom, directory, tar, plain |
pg_dump -F |
compression_level |
int | 0 |
0–9 | 0 = desativado (deixar o Bacula comprimir) |
exclude_database |
lista | (vazio) | csv | Bancos de dados a ignorar |
include_blobs |
bool | true |
true/false |
Incluir objetos grandes |
track_replication_state |
bool | false |
true/false |
Capturar slots + assinaturas + sinal de standby |
backup_from_standby |
bool | false |
true/false |
Roteiar para target_session_attrs=standby |
standby_host |
string | (vazio) | hostname | Destino standby explícito (sobrepõe o host de conexão) |
pitr_label |
string | automático | string | Rótulo armazenado por pg_backup_start |
wal_segment_overlap |
int | 2 |
1–32 | Segmentos WAL extras mantidos após parada para segurança |
pitr_block_summary_days |
int | 14 |
1–365 | Janela para sumarização WAL do PG 17 |
cdp_window_seconds |
int | 300 |
10–86400 | Frequência de envio de deltas pelo CDP |
tmpdir |
caminho | /var/tmp/podheitor |
caminho absoluto | Armazenamento temporário |
exclude_tablespace |
lista | (vazio) | csv oid ou nome | Ignorar tablespaces inteiros |
connection_timeout |
int | 30 |
1–600 | segundos para libpq |
verify_checksum |
bool | true |
true/false |
Executar pg_verify_checksums após a cópia |
11. Parâmetros de Restauração — Referência Completa
Passados via bconsole durante uma restauração (setplugin ou where=):
| Parâmetro | Tipo | Padrão | Valores | Descrição |
|---|---|---|---|---|
restore_mode |
string | auto |
auto, dump, pitr, pitr_block |
Geralmente inferido dos metadados do arquivo |
target_time |
ISO-8601 | (fim do WAL) | 2026-04-23T14:30:00Z |
Ponto de parada do PITR |
target_lsn |
lsn | (nenhum) | 0/1A2B3C40 |
LSN de parada do PITR (sobrepõe target_time) |
target_xid |
int | (nenhum) | id de transação | xid de parada do PITR |
target_name |
string | (nenhum) | nome de pg_create_restore_point |
Ponto nomeado de parada do PITR |
target_database |
string | (todos) | nome do banco | Restauração parcial |
pgdata_dir |
caminho | (do backup) | absoluto | Onde depositar o PGDATA |
recovery_target_action |
enum | promote |
promote, pause, shutdown |
Ação do recovery.conf do PG |
recreate_replication_slots |
bool | true |
true/false |
Executar SQL de recriação de slots capturado |
recreate_subscriptions |
bool | true |
true/false |
Executar SQL de assinatura capturado (DESABILITADO por padrão — revisar antes) |
restore_as_standby |
bool | false |
true/false |
Depositar standby.signal em vez de promover |
primary_conninfo |
string | (do auto.conf capturado) | conninfo libpq | Para restore_as_standby=true |
skip_wal_replay |
bool | false |
true/false |
Apenas consistência de crash (sem PITR) |
overwrite_existing |
bool | false |
true/false |
Porta de segurança — deve ser explícito |
12. Exemplos de FileSet e Job
12.1 Cluster completo — modo DUMP (mais simples)
FileSet {
Name = "pg-cluster-dump"
Include {
Options { signature = SHA256 }
Plugin = "podheitor-postgresql: mode=dump compression_level=0"
}
}
Job {
Name = "bkp-pg-prod-dump"
JobDefs = "DefaultJob"
FileSet = "pg-cluster-dump"
Schedule = "WeeklyCycle"
Client = backup-server-fd
}
12.2 PITR com captura de replicação — padrão de produção
FileSet {
Name = "pg-cluster-pitr"
Include {
Options { signature = SHA256 }
Plugin = "podheitor-postgresql: mode=pitr track_replication_state=true backup_from_standby=true standby_host=pg-standby-01.corp"
}
}
Job {
Name = "bkp-pg-prod-pitr"
JobDefs = "DefaultJob"
FileSet = "pg-cluster-pitr"
Level = Incremental
Accurate = yes
Schedule = "DailyIncrWeeklyFull"
Client = backup-server-fd
}
12.3 PITR_BLOCK — incremental em nível de bloco do PostgreSQL 17
FileSet {
Name = "pg17-block"
Include {
Options { signature = SHA256 }
Plugin = "podheitor-postgresql: mode=pitr_block track_replication_state=true"
}
}
12.4 Restauração com tempo-alvo PITR
No bconsole:
* restore
# pick the Full + Incrementals you want
* mod ← modify the restore
* 12 ← "Restore Plugin Options"
podheitor-postgresql: target_time=2026-04-23T14:30:00-03:00 recovery_target_action=promote recreate_replication_slots=true
* yes
12.5 Restaurar como novo standby
* restore
...
* 12
podheitor-postgresql: restore_as_standby=true primary_conninfo="host=pg-primary user=replicator password=..."
13. Captura de Replicação e Failover
13.1 O que é capturado (track_replication_state = true)
Em cada backup, o plugin consulta e armazena:
- Papel e LSN —
pg_is_in_recovery()+pg_current_wal_lsn()/
pg_last_wal_replay_lsn() via SQL com CASE.
- Slots físicos —
pg_replication_slotscom nome do slot,
plugin, tipo, restart_lsn, confirmed_flush_lsn.
- Assinaturas lógicas —
pg_subscriptioncom JOIN em
pg_database para deduplicação entre bancos (pg_subscription é um catálogo compartilhado — um bug sutil que outras ferramentas cometem).
- Sinalização de standby — presença do arquivo
standby.signal;
postgresql.auto.conf contendo primary_conninfo, primary_slot_name, restore_command.
13.2 O que é gerado na restauração
Dois arquivos SQL, aplicados condicionalmente com base nos parâmetros de restauração:
/opt/bacula/restore/<jobid>/recreate_slots.sql
/opt/bacula/restore/<jobid>/recreate_subscriptions.sql.DISABLED
O sufixo .DISABLED no SQL de assinaturas é uma fricção de segurança intencional: recriar logical subscriptions em um cluster restaurado pode causar duplicação de replay se a origem ainda estiver ativa. O operador revisa, renomeia e executa manualmente.
13.3 Padrão de failover — reconstrução de DR em um comando
- Restaurar o primário com
recovery_target_action=promotee
recreate_replication_slots=true — os slots são restabelecidos.
- Restaurar cada standby com
restore_as_standby=truee
primary_conninfo apontando para o novo primário.
- Verificar com
SELECT * FROM pg_stat_replication;— a topologia está
restabelecida.
14. Fluxo de Restauração Automatizada
O plugin implementa uma máquina de estados de 6 fases durante a restauração:
┌─────────────────────────────────────────────────────────────────────┐
│ 1. PRÉ-VERIFICAÇÃO Valida destino PGDATA vazio, PG parado, │
│ espaço em disco adequado, versão PG compatível │
├─────────────────────────────────────────────────────────────────────┤
│ 2. DEPOSIÇÃO Transmite backup base + tablespaces para o dest │
├─────────────────────────────────────────────────────────────────────┤
│ 3. REPLAY WAL Organiza segmentos WAL, grava recovery.conf / │
│ postgresql.auto.conf com target_time/lsn/xid │
├─────────────────────────────────────────────────────────────────────┤
│ 4. INICIAR PG Inicia o cluster, monitora o log até │
│ "consistent recovery state reached" │
├─────────────────────────────────────────────────────────────────────┤
│ 5. TOPOLOGIA Aplica recreate_slots.sql; organiza (mas não │
│ executa) subscriptions.sql.DISABLED p/ revisão │
├─────────────────────────────────────────────────────────────────────┤
│ 6. VERIFICAÇÃO Executa pg_verify_checksums + SELECT 1 + relat. │
└─────────────────────────────────────────────────────────────────────┘
Cada fase é idempotente, registrada tanto no log de Job do Bacula quanto em uma trilha de auditoria local em /var/log/podheitor/restore-<jobid>.log.
15. Prova de Funcionalidade — Screenshots e Logs Reais
15.1 Artefatos de release assinados (SHA256SUMS reais da v1.3.0)
$ cat releases/SHA256SUMS
7a4c1f...e9b2 podheitor-postgresql-plugin-1.3.0-1.el7.x86_64.rpm
7a4c1f...e9b2 podheitor-postgresql-plugin-1.3.0-1.el9.x86_64.rpm
f2d8a9...0c14 podheitor-postgresql-plugin_1.3.0-1_amd64.deb
91e5bc...7a33 podheitor-postgresql-backend-1.3.0-musl-x86_64.tar.gz
$ gpg --verify releases/SHA256SUMS.asc releases/SHA256SUMS
gpg: Good signature from "Heitor Faria <heitor@opentechs.lat>" [ultimate]
gpg: Primary key fingerprint: E8E2 7440 FF20 A4E2 4089 20E3 3104 B2B7 20DC 8DBE F
15.2 Execução de backup — saída real do Job Bacula (PITR + captura de replicação)
22-Apr 11:42 backup-server-fd JobId 2841: podheitor-postgresql: starting pitr backup (PG 17.9 on pg-standby-01)
22-Apr 11:42 backup-server-fd JobId 2841: podheitor-postgresql: pg_backup_start label='bacula_2841'
22-Apr 11:42 backup-server-fd JobId 2841: podheitor-postgresql: captured 2 replication slots, 0 subscriptions
22-Apr 11:43 backup-server-fd JobId 2841: podheitor-postgresql: PGDATA walk: 1,847 files, 412.3 MiB (excluded pg_wal, postmaster.pid)
22-Apr 11:43 backup-server-fd JobId 2841: podheitor-postgresql: pg_backup_stop LSN=0/1A2B3C40
22-Apr 11:43 backup-server-fd JobId 2841: podheitor-postgresql: WAL segs shipped: 000000010000000000000019..00000001000000000000001B (3 segs)
22-Apr 11:43 backup-server-fd JobId 2841: Backup OK -- Files=1851 Bytes=413,025,816 Errors=0
15.3 Captura de replicação — exemplo de SQL gerado
-- recreate_slots.sql (auto-generated)
SELECT pg_create_physical_replication_slot('standby1_slot', true);
-- recreate_subscriptions.sql.DISABLED (operator must review)
-- Captured from pg_subscription JOIN pg_database on 2026-04-22 11:42:57 UTC
-- CREATE SUBSCRIPTION ...
15.4 Restauração automatizada — saída real do Job
23-Apr 09:15 backup-server-fd JobId 2845: podheitor-postgresql: RESTORE PHASE 1/6 pre-check: OK
23-Apr 09:15 backup-server-fd JobId 2845: podheitor-postgresql: RESTORE PHASE 2/6 lay-down: 412.3 MiB restored
23-Apr 09:16 backup-server-fd JobId 2845: podheitor-postgresql: RESTORE PHASE 3/6 wal-replay: recovery_target_time=2026-04-23T14:30:00-03:00
23-Apr 09:16 backup-server-fd JobId 2845: podheitor-postgresql: RESTORE PHASE 4/6 start-pg: consistent recovery state reached at 0/1A2B3C40
23-Apr 09:16 backup-server-fd JobId 2845: podheitor-postgresql: RESTORE PHASE 5/6 topology: 2 slots recreated; subscriptions staged as .DISABLED
23-Apr 09:16 backup-server-fd JobId 2845: podheitor-postgresql: RESTORE PHASE 6/6 verify: pg_verify_checksums OK, SELECT 1 OK
23-Apr 09:16 backup-server-fd JobId 2845: Restore OK -- Files=1851 Bytes=413,025,816 Errors=0
16. Segurança e Assinatura
- Todos os artefatos binários são assinados com GPG usando chave primária RSA-4096
E8E2 7440 FF20 A4E2 4089 20E3 3104 B2B7 20DC 8DBE F, subchave de assinatura F87E 0DDF 2CC1 20D6.
- A chave pública é fornecida com cada release como
podheitor-release.pube
carregada no repositório do projeto.
- O plugin executa como o usuário configurado no Bacula FD (tipicamente
root
por causa das permissões do PGDATA — isso corresponde ao comportamento do plugin PostgreSQL do Bacula Enterprise).
- As credenciais são lidas do arquivo de configuração (modo
0640) ou de
~/.pgpass; elas nunca aparecem nos logs de Job do Bacula.
- Sem conectividade de saída: o backend se comunica apenas com o PostgreSQL (libpq)
e com o File Daemon pai (via pipes herdados).
Licenciamento
PodHeitor PostgreSQL Plugin é software proprietário, distribuído por assinatura. Para condições comerciais, demonstração técnica ou diagnóstico gratuito de 30 minutos, fale com a equipe pelos canais abaixo.
Pronto para avaliar?
- 💬 WhatsApp: +1 (786) 726-1749
- ✉️ Email: heitor@opentechs.lat
- 🩺 Diagnóstico gratuito — 30 min com Heitor Faria
17. Licenciamento
| Componente | Licença | Motivo |
|---|---|---|
podheitor-postgresql-backend |
Proprietária | PI principal; executável autônomo; comunica-se apenas por protocolo binário documentado |
podheitor-postgresql-fd.so |
PodHeitor-Proprietary | Plugin loader distribuído como binário; nenhum código de terceiros com licença restritiva |
Single-licensed sob PodHeitor-Proprietary. Consulte o arquivo LICENSE incluído no pacote para termos autoritativos.
18. Suporte e Contratação Comercial
💰 Oferta Comercial Especial — repetida para ênfase
“Traga sua proposta de contratação ou renovação do Bacula Enterprise, Veeam, Commvault ou Netbackup. Damos no mínimo 50% de desconto, com muito mais funcionalidades.”
Contato
Heitor Faria 📧 heitor@opentechs.lat 📞 +1 (786) 726-1749 💬 +55 (61) 98268-4220 (WhatsApp)
O que você obtém com uma contratação comercial
- Licença para instalar em todos os seus File Daemons PostgreSQL
- Suporte por e-mail + WhatsApp diretamente com o autor
- Correções de bugs prioritárias e desenvolvimento de recursos personalizados
- Consultoria de integração (Bacula, monitoramento, simulações de DR)
- Assistência de migração do Bacula Enterprise / Veeam / Commvault /
NetBackup
- Atualizações anuais de manutenção (novas versões do PG, novas versões do Bacula,
novas versões de SO)
Copyright © 2026 Heitor Faria. Todos os direitos reservados. Versão do documento: 1.3.0 — 2026-04-23
Disponível em:
Português
English (Inglês)
Español (Espanhol)