Whitepaper — PodHeitor PostgreSQL

Whitepaper — PodHeitor PostgreSQL

Respaldo PostgreSQL con PITR al segundo. pg_basebackup nativo + archivado WAL continuo, sin ventana de mantenimiento, restauración punto-en-tiempo sub-minuto.

  • Base backup en caliente vía pg_basebackup — sin bloquear escritura.
  • WAL archiving continuo — RPO cerca de cero, recovery al segundo exacto.
  • Compatible 9.6 → 16+ — un plugin para todas las versiones en producción.
  • Integración streaming replication — respaldo desde standby, cero overhead en primario.
  • Validación automática — pg_verifybackup post-job, alerta de drift.

Producción en 30 días, al menos 50% más barato. Trial gratuito, RPMs y DEBs firmados, soporte directo con Heitor Faria. Reemplace su licencia Veeam, Commvault o Bacula Enterprise sin romper la ventana nocturna.

Solicitar trial gratuito de 30 días →

💰 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.»

«Tráiganos su propuesta de contrato o renovación de Bacula Enterprise, Veeam, Commvault o Netbackup. Ofrecemos al menos un 50 % de descuento — y significativamente más funcionalidades.»

Contacto — Heitor Faria 📧 heitor@opentechs.lat 📞 +1 (786) 726-1749 💬 +55 (61) 98268-4220 (WhatsApp)


Índice

  1. Resumen Ejecutivo
  2. Por Qué Existe Este Plugin
  3. Casos de Uso
  4. Descripción General de la Arquitectura
  5. Comparativa de Funcionalidades vs. Alternativas Comerciales
  6. Requisitos del Sistema y Compatibilidad
  7. Dimensionamiento Recomendado
  8. Procedimiento de Instalación
  9. Manual de Configuración
  10. Parámetros de Backup — Referencia Completa
  11. Parámetros de Restauración — Referencia Completa
  12. Ejemplos de FileSet y Job
  13. Captura de Replicación y Failover
  14. Flujo de Restauración Automatizada
  15. Prueba de Funcionalidad — Capturas y Registros Reales
  16. Seguridad y Firma
  17. Licenciamiento
  18. Soporte y Contratación Comercial

1. Resumen Ejecutivo

PodHeitor PostgreSQL Backup and Replication Plugin for Bacula es un metaplugin de nivel productivo que convierte PodHeitor Backup Edition (gratuito, código abierto) en una plataforma completa de protección de datos PostgreSQL que iguala o supera el conjunto de funcionalidades de los productos comerciales de backup premium — a una fracción de su costo total de propiedad.

Cubre la brecha más importante en el stack Bacula de código abierto: integración nativa con PostgreSQL, con soporte a metaplugin, incluyendo incremental a nivel de bloque, Point-In-Time Recovery (PITR), Protección Continua de Datos (CDP), y captura de topología de replicación — funcionalidades que, hasta ahora, requerían licenciamiento propietario de Bacula Enterprise o herramientas pesadas de terceros como Veeam, Commvault o Veritas NetBackup.

Principales Diferenciadores

Capacidad PodHeitor (este plugin) Bacula Enterprise Veeam / Commvault / NB
Funciona en Bacula Community ❌ (solo enterprise) N/A
PITR (basado en WAL)
Incremental a nivel de bloque (PG 17 pg_combinebackup) ⚠️ parcial
Captura de topología de replicación + recreación automática
Backup solo desde standby (descarga del primario) ⚠️
Modo de Protección Continua de Datos (CDP) ⚠️
Binarios completamente firmados (GPG RSA-4096)
Restauración automatizada con un solo comando ⚠️
Costo de licenciamiento (por FD / por TB) US$ 0 – tarifa plana baja US$ $$$ US$ $$$$

Cifras Clave

  • 5 modos de backup: dump, parallel_dump, pitr, pitr_block, cdp
  • 115 pruebas unitarias + validación E2E contra un clúster real de PostgreSQL 17
  • Probado en: PostgreSQL 12 → 17, CentOS 7 → RHEL 9, Debian 11/12, Oracle Linux 9.6
  • Línea base glibc-2.17 — un único binario RPM que funciona en todos

los Linux empresariales convencionales desde 2014

  • Releases con doble firma: clave RSA-4096

E8E2744FF20A4E2408920E33104B2B720DC8DBEF


2. Por Qué Existe Este Plugin

PodHeitor Backup Edition es el sistema de backup empresarial de código abierto más ampliamente implementado en el mundo. Protege Linux, Windows, VMs, almacenamiento en objetos, cintas — todo, excepto bases de datos, de forma nativa.

La arquitectura oficial de metaplugin existe en Community Edition, pero las integraciones con bases de datos se incluyen únicamente con la suscripción de pago de Bacula Enterprise. Esto obliga a los usuarios de código abierto a elegir entre tres caminos insatisfactorios:

  1. Pagar por Bacula Enterprise — comienza en decenas de miles

de US$ al año para un entorno de tamaño mediano.

  1. Desarrollar su propia solución — scripts frágiles, sin PITR,

sin modo Accurate, sin streaming desde el File Daemon.

  1. Adoptar una segunda herramienta (Veeam, Commvault, NetBackup) — infraestructura

duplicada, licenciamiento duplicado, carga operativa duplicada.

PodHeitor cierra esta brecha. Es un metaplugin desarrollado desde cero que se integra de forma nativa con la arquitectura de metaplugin del PodHeitor Backup, de modo que todas las funcionalidades de PodHeitor Backup — modo Accurate, programación Differential/Incremental, cifrado, deduplicación, bibliotecas de cinta, almacenamiento en nube — funcionan sin modificaciones.


3. Casos de Uso

3.1 Base de datos única — PYME / mercado intermedio

«Ya usamos PodHeitor Backup para nuestros archivos y VMs. Necesitamos backups de PostgreSQL con PITR. No queremos pagar por Bacula Enterprise.»

→ Instale el RPM/DEB, agregue una línea Plugin a su FileSet y programe. Listo en 15 minutos. Sin infraestructura duplicada.

3.2 Gran entorno PostgreSQL con streaming replication

«Tenemos 20 clústeres PostgreSQL, cada uno con 1–3 standbys. Necesitamos incremental a nivel de bloque y necesitamos reconstruir la topología de replicación tras una restauración de DR.»

→ Modo pitr_block + track_replication_state = true. El plugin captura pg_replication_slots, pg_subscription, y el standby_signal / postgresql.auto.conf de cada standby. En la restauración, regenera los archivos SQL y de configuración para que la topología quede intacta.

3.3 Sectores regulados (finanzas, salud, gobierno)

«Necesitamos PITR al segundo, cadena de custodia auditable en los medios de backup y binarios firmados.»

→ El modo PITR escribe segmentos WAL en volúmenes administrados por Bacula con integridad criptográfica (firma de bloque SHA-256 nativa de Bacula). Los binarios del plugin están firmados con GPG mediante una clave RSA de 4.096 bits publicada en una URL conocida.

3.4 Canje de renovación — escenario comercial

«Nuestra renovación de Bacula Enterprise / Veeam / Commvault / NetBackup llegó a seis cifras. ¿Qué pueden ofrecernos?»

→ Vea el aviso al inicio de este documento. Al menos un 50 % de descuento, con más funcionalidades. Tráiganos la propuesta.


4. Descripción General de la Arquitectura

┌──────────────┐         ┌──────────────┐         ┌───────────────┐
│   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    │
                      └──────────────────┘

División de Componentes

Componente Lenguaje Licencia Función
podheitor-postgresql-fd.so Rust PodHeitor-Proprietary Plugin loader del Bacula FD — traduce callbacks a llamadas del backend
podheitor-postgresql-backend Rust Propietaria Toda la lógica PostgreSQL: backup, restauración, replicación, WAL, PITR
podheitor-postgresql.conf texto N/A Conexión, rol, credenciales, opciones

La división es deliberada: el adaptador C con licencia GPL es mínimo y abierto; la propiedad intelectual reside en el backend Rust propietario como un subproceso completamente aislado que se comunica únicamente a través de un protocolo binario documentado.


5. Comparativa de Funcionalidades vs. Alternativas Comerciales

Funcionalidad PodHeitor v1.3 Bacula Enterprise 18 Veeam B&R 12 Commvault 11 Veritas NetBackup 10
Funciona en PodHeitor Backup (gratuito)
Integración nativa como metaplugin de Bacula N/A N/A N/A
DUMP (pg_dump)
DUMP paralelo (-j) ⚠️ ⚠️ ⚠️
PITR — completo/diferencial/incremental
Incremental a nivel de bloque (PG 17) ⚠️
Modo CDP ⚠️ ⚠️
Backup solo desde standby ⚠️ ⚠️ ⚠️
Captura de topología de replicación
Restauración automatizada en 6 fases ⚠️ ⚠️
Compatible con el modo Accurate de Bacula N/A N/A N/A
Binarios firmados con GPG
Costo: 1 FD + 500 GB PG (lista, 1 año) negociado — hasta un 50 % de descuento sobre su propuesta ~US$ 15.000 ~US$ 12.000 ~US$ 20.000 ~US$ 18.000

Leyenda: ✅ soporte nativo completo | ⚠️ parcial/mediante script/licenciamiento adicional | ❌ no soportado


6. Requisitos del Sistema y Compatibilidad

Versiones soportadas de PostgreSQL

Versión DUMP DUMP Paralelo PITR PITR_BLOCK CDP Captura de replicación
12
13
14
15
16
17

pitr_block requiere la utilidad pg_combinebackup de PostgreSQL 17; los demás modos funcionan desde PG 12 en adelante.

Versiones soportadas de Bacula

Distribución Bacula Versión mínima Probado
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, contáctenos

Distribuciones Linux soportadas (para el host del plugin / File Daemon)

Distribución Paquete glibc Probado
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
Cualquier glibc ≥ 2.17 (sin .deb/.rpm) *.musl.tar.gz estático

Arquitectura: solo x86_64 en v1.3. ARM64 está en el roadmap de v2.0.

Otros requisitos

Requisito Detalle
postgresql-client ≥ 14 psql, pg_dump, pg_restore, pg_basebackup, pg_combinebackup (PG 17) en el host del plugin
Conectividad de red Host del plugin → PostgreSQL (TCP, puerto 5432 por defecto) + File Daemon ↔ Storage Daemon
Credenciales Un rol PG con REPLICATION, pg_read_all_data y (para captura de replicación) pg_read_all_settings
Disco (host del plugin, almacenamiento temporal) 1× tamaño del mayor clúster de base de datos durante pitr_block (opcional; transmitido de otro modo)

7. Dimensionamiento Recomendado

Host del plugin (típicamente = host del File Daemon)

Métrica Pequeño (<100 GB PG) Mediano (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 (almacenamiento temporal) 10 GB 50 GB 200 GB 500 GB+
Red (hacia PG) 1 GbE 1 GbE 10 GbE 10 GbE+
Red (hacia SD) 1 GbE 10 GbE 10 GbE 25 GbE+

Servidor PostgreSQL (sin dimensionamiento adicional más allá de la operación normal)

  • max_wal_senders ≥ 2 (uno para el plugin, uno para los standbys existentes)
  • wal_level = replica (o logical si usa logical replication)
  • archive_mode = on no es obligatorio — el plugin utiliza pg_backup_start/stop + streaming WAL directo; pero también soportamos configuraciones con archive-mode.
  • Para pitr_block: summarize_wal = on (PG 17+)

Storage Daemon de Bacula

Dimensione como lo haría para cualquier carga de trabajo de backup de volumen equivalente. El plugin emite streams estándar de Bacula, por lo que las guías de dimensionamiento existentes del SD se aplican íntegramente — sin sobrecarga específica del plugin.


8. Procedimiento de Instalación

8.1 Verificar firmas (recomendado)

Descargue la clave pública una vez:

Luego verifique cada artefacto:

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 Instalación vía 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 Instalación vía 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 (cualquier 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 Archivos instalados por el paquete</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 Prueba básica post-instalación

/opt/bacula/bin/podheitor-postgresql-backend --version
# expected: podheitor-postgresql-backend 1.3.0

9. Manual de Configuración

9.1 Configuración del File Daemon

Agregue a /opt/bacula/etc/bacula-fd.conf (o al equivalente en configuración dividida):

FileDaemon {
    Name         = backup-server-fd
    Plugin Directory = /opt/bacula/plugins
    Plugin Names     = "podheitor-postgresql-fd"
    # ... existing options ...
}

Luego recargue:

sudo systemctl reload bacula-fd

9.2 Configuración de conexión del 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 Rol 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 — Referencia Completa

Se pasan mediante la directiva Plugin del FileSet:

Plugin = "podheitor-postgresql: mode=<mode> <param>=<value> ..."
Parámetro Tipo Valor por defecto Valores Descripción
mode string dump dump, parallel_dump, pitr, pitr_block, cdp Estrategia de backup
database string * (todas) nombre de base de datos o lista separada por comas Qué base(s) de datos respaldar
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 = desactivado (dejar que Bacula comprima)
exclude_database lista (vacío) csv Bases de datos a omitir
include_blobs bool true true/false Incluir objetos grandes
track_replication_state bool false true/false Capturar slots + suscripciones + señal de standby
backup_from_standby bool false true/false Enrutar a target_session_attrs=standby
standby_host string (vacío) hostname Destino standby explícito (anula el host de conexión)
pitr_label string automático string Etiqueta almacenada por pg_backup_start
wal_segment_overlap int 2 1–32 Segmentos WAL adicionales conservados tras la parada por seguridad
pitr_block_summary_days int 14 1–365 Ventana para la sumarización WAL de PG 17
cdp_window_seconds int 300 10–86400 Frecuencia con que CDP envía deltas
tmpdir ruta /var/tmp/podheitor ruta absoluta Almacenamiento temporal
exclude_tablespace lista (vacío) csv oid o nombre Omitir tablespaces completos
connection_timeout int 30 1–600 segundos para libpq
verify_checksum bool true true/false Ejecutar pg_verify_checksums tras la copia

11. Parámetros de Restauración — Referencia Completa

Se pasan mediante bconsole durante una restauración (setplugin o where=):

Parámetro Tipo Valor por defecto Valores Descripción
restore_mode string auto auto, dump, pitr, pitr_block Generalmente inferido de los metadatos del archivo
target_time ISO-8601 (fin del WAL) 2026-04-23T14:30:00Z Punto de parada del PITR
target_lsn lsn (ninguno) 0/1A2B3C40 LSN de parada del PITR (anula target_time)
target_xid int (ninguno) id de transacción xid de parada del PITR
target_name string (ninguno) nombre de pg_create_restore_point Punto nombrado de parada del PITR
target_database string (todas) nombre de base de datos Restauración parcial
pgdata_dir ruta (del backup) absoluta Dónde depositar el PGDATA
recovery_target_action enum promote promote, pause, shutdown Acción del recovery.conf de PG
recreate_replication_slots bool true true/false Ejecutar SQL de recreación de slots capturado
recreate_subscriptions bool true true/false Ejecutar SQL de suscripción capturado (DESHABILITADO por defecto — revisar antes)
restore_as_standby bool false true/false Depositar standby.signal en lugar de promover
primary_conninfo string (del auto.conf capturado) conninfo libpq Para restore_as_standby=true
skip_wal_replay bool false true/false Solo consistencia de crash (sin PITR)
overwrite_existing bool false true/false Compuerta de seguridad — debe ser explícito

12. Ejemplos de FileSet y Job

12.1 Clúster completo — modo DUMP (más simple)

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 con captura de replicación — patrón de producción

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 a nivel de bloque de PostgreSQL 17

FileSet {
    Name = "pg17-block"
    Include {
        Options { signature = SHA256 }
        Plugin = "podheitor-postgresql: mode=pitr_block track_replication_state=true"
    }
}

12.4 Restauración con tiempo objetivo PITR

En 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 nuevo standby

* restore
...
* 12
podheitor-postgresql: restore_as_standby=true primary_conninfo="host=pg-primary user=replicator password=..."

13. Captura de Replicación y Failover

13.1 Qué se captura (track_replication_state = true)

En cada backup, el plugin consulta y almacena:

  1. Rol y LSNpg_is_in_recovery() + pg_current_wal_lsn() /

pg_last_wal_replay_lsn() mediante SQL con CASE.

  1. Slots físicospg_replication_slots con nombre del slot,

plugin, tipo, restart_lsn, confirmed_flush_lsn.

  1. Suscripciones lógicaspg_subscription con JOIN en

pg_database para deduplicación entre bases de datos (pg_subscription es un catálogo compartido — un error sutil que otras herramientas cometen).

  1. Señalización de standby — presencia del archivo standby.signal;

postgresql.auto.conf que contiene primary_conninfo, primary_slot_name, restore_command.

13.2 Qué se genera en la restauración

Dos archivos SQL, aplicados condicionalmente según los parámetros de restauración:

/opt/bacula/restore/<jobid>/recreate_slots.sql
/opt/bacula/restore/<jobid>/recreate_subscriptions.sql.DISABLED

El sufijo .DISABLED en el SQL de suscripciones es una fricción de seguridad intencional: recrear logical subscriptions en un clúster restaurado puede causar duplicación de replay si el origen aún está activo. El operador revisa, renombra y ejecuta manualmente.

13.3 Patrón de failover — reconstrucción de DR en un solo comando

  1. Restaurar el primario con recovery_target_action=promote y

recreate_replication_slots=true — los slots se restablecen.

  1. Restaurar cada standby con restore_as_standby=true y

primary_conninfo apuntando al nuevo primario.

  1. Verificar con SELECT * FROM pg_stat_replication; — la topología está

restablecida.


14. Flujo de Restauración Automatizada

El plugin implementa una máquina de estados de 6 fases durante la restauración:

┌─────────────────────────────────────────────────────────────────────┐
│  1. PRE-VERIFICACIÓN  Valida destino PGDATA vacío, PG detenido,      │
│                       espacio en disco adecuado, versión PG coincide │
├─────────────────────────────────────────────────────────────────────┤
│  2. DEPOSICIÓN        Transmite el backup base + tablespaces al dest │
├─────────────────────────────────────────────────────────────────────┤
│  3. REPLAY WAL        Organiza segmentos WAL, escribe recovery.conf /│
│                       postgresql.auto.conf con target_time/lsn/xid  │
├─────────────────────────────────────────────────────────────────────┤
│  4. INICIAR PG        Inicia el clúster, monitorea el log hasta      │
│                       "consistent recovery state reached"            │
├─────────────────────────────────────────────────────────────────────┤
│  5. TOPOLOGÍA         Aplica recreate_slots.sql; organiza (pero no   │
│                       ejecuta) subscriptions.sql.DISABLED p/ revisión│
├─────────────────────────────────────────────────────────────────────┤
│  6. VERIFICACIÓN      Ejecuta pg_verify_checksums + SELECT 1 + informe│
└─────────────────────────────────────────────────────────────────────┘

Cada fase es idempotente, registrada tanto en el log de Job de Bacula como en un registro de auditoría local en /var/log/podheitor/restore-<jobid>.log.


15. Prueba de Funcionalidad — Capturas y Registros Reales

15.1 Artefactos de release firmados (SHA256SUMS reales de la 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 Ejecución de backup — salida real del Job Bacula (PITR + captura de replicación)

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 replicación — ejemplo de SQL generado

-- 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 Restauración automatizada — salida real del 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. Seguridad y Firma

  • Todos los artefactos binarios están firmados con GPG usando la clave primaria RSA-4096

E8E2 7440 FF20 A4E2 4089 20E3 3104 B2B7 20DC 8DBE F, subclave de firma F87E 0DDF 2CC1 20D6.

  • La clave pública se incluye con cada release como podheitor-release.pub y se

carga en el repositorio del proyecto.

  • El plugin se ejecuta como el usuario configurado en Bacula FD (típicamente root

debido a los permisos de PGDATA — esto coincide con el comportamiento del plugin PostgreSQL de Bacula Enterprise).

  • Las credenciales se leen del archivo de configuración (modo 0640) o de

~/.pgpass; nunca aparecen en los logs de Job de Bacula.

  • Sin conectividad de salida: el backend solo se comunica con PostgreSQL (libpq)

y con el File Daemon padre (a través de pipes heredados).


Licenciamiento

PodHeitor PostgreSQL Plugin es software propietario, distribuido por suscripción. Para condiciones comerciales, demostración técnica o diagnóstico gratuito de 30 minutos, habla con el equipo por los canales abajo.

¿Listo para evaluar?

17. Licenciamiento

Componente Licencia Motivo
podheitor-postgresql-backend Propietaria PI principal; ejecutable independiente; se comunica solo a través del protocolo binario documentado
podheitor-postgresql-fd.so (Rust ) PodHeitor-Proprietary Loader pure-Rust construido del

Single-licensed bajo PodHeitor-Proprietary. Consulte el archivo LICENSE incluido en el paquete para términos autoritativos.


18. Soporte y Contratación Comercial

💰 Oferta Comercial Especial — repetida para énfasis

«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.»

Contacto

Heitor Faria 📧 heitor@opentechs.lat 📞 +1 (786) 726-1749 💬 +55 (61) 98268-4220 (WhatsApp)

Qué incluye una contratación comercial

  • Licencia para instalar en todos sus File Daemons PostgreSQL
  • Soporte por correo electrónico + WhatsApp directamente con el autor
  • Correcciones de errores prioritarias y desarrollo de funcionalidades personalizadas
  • Consultoría de integración (Bacula, monitoreo, simulacros de DR)
  • Asistencia de migración desde Bacula Enterprise / Veeam / Commvault /

NetBackup

  • Actualizaciones anuales de mantenimiento (nuevas versiones de PG, nuevas versiones de Bacula,

nuevas versiones de SO)


Copyright © 2026 Heitor Faria. Todos los derechos reservados. Versión del documento: 1.3.0 — 2026-04-23

Disponível em: pt-brPortuguês (Portugués, Brasil)enEnglish (Inglés)esEspañol

Deja una respuesta