Technical whitepaper — PodHeitor Firebird for Bacula

Commercial-grade Rust plugin for Firebird 3/4/5 on Bacula Community 15.0.3+, closing a real gap: Bacula Enterprise does not ship a Firebird plugin. Three modes (gbak dump, nbackup chain L0..LN, FB ≥4 replication-log shipping), cross-version migration, FB 5 parallel workers (gbak -par), encryption-at-rest passthrough.

Companion technical document to the PodHeitor Firebird plugin page.

1. The white space — Firebird with no native plugin

Bacula Enterprise 18.2.3 ships PostgreSQL and MySQL plugins, but does not ship a Firebird plugin. In markets like Brazil/LatAm, that is a concrete gap: Firebird still dominates legacy ERPs (TOTVS Protheus, public-sector management systems), EMR/HIS, and embedded applications. Without a plugin, the current backup path is:

  • Ad-hoc gbak to a file + Bacula backup of the file (two steps, no coordination).
  • Manual nbackup with no chain management — Bacula doesn’t correlate levels.
  • FS-level snapshot of the .fdb (risks DB inconsistency if the lock file isn’t honoured).

The PodHeitor Firebird Plugin is the first native plugin, and the only one in the PodHeitor family closing this gap completely — three modes covering every window-vs-granularity-vs-RPO tradeoff.

2. Architecture — cdylib + standalone backend, PodHeitor pattern

┌──────────────────────────────────────────────────────────────┐
│  Bacula File Daemon (FD) — bacula-fd 15.0.3+                 │
│  loads /opt/bacula/plugins/podheitor-firebird-fd.so          │
│         (Rust cdylib, ~600 KB)                               │
└──────────────────────────────┬───────────────────────────────┘
                               │ fork+exec (PTCOMM via stdin/stdout)
                               ▼
┌──────────────────────────────────────────────────────────────┐
│  /opt/bacula/bin/podheitor-firebird-backend  (Rust binary)   │
│                                                              │
│  ┌─────────────────────┐ ┌─────────────────────┐             │
│  │ DumpEngine          │ │ NbackupEngine       │             │
│  │ (gbak, FB5 -par)    │ │ (chain L0..LN)      │             │
│  └─────────────────────┘ └─────────────────────┘             │
│  ┌─────────────────────┐ ┌─────────────────────┐             │
│  │ ReplayEngine        │ │ RestoreEngine       │             │
│  │ (FB4 log shipping)  │ │ (in-place chain)    │             │
│  └─────────────────────┘ └─────────────────────┘             │
│  ┌─────────────────────────────────────────────┐             │
│  │ FirebirdAdapter — services API + libfbclient │             │
│  │ Local: spawn gbak/nbackup     Remote: TCP    │             │
│  └─────────────────────────────────────────────┘             │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐                  │
│  │ Parallel │ │ Compress │ │ Throttle /   │                  │
│  │ Executor │ │ (zstd…)  │ │ BW shaper    │                  │
│  └──────────┘ └──────────┘ └──────────────┘                  │
└──────────────────────────────────────────────────────────────┘

Same pattern as podheitor-postgresql / podheitor-mssql / podheitor-oracle: Rust cdylib dlopen’d by bacula-fd, fork+exec of the standalone backend, PTCOMM communication (length-tagged framing on stdin/stdout). Crash isolation; AGPLv3 license firewall; no Bacula source statically linked.

3. Three modes — natural mapping to Firebird

Mode When to choose Mechanism
dump DB ≤ 50 GB; table-level granularity; cross-version migration gbak -b streaming; FB 5 with gbak -par N (native parallel workers)
nbackup DB ≥ 50 GB; short backup window L0..LN page-level chain; in-place restore (zero staging)
replay RPO ≈ minutes; multi-site DR; FB ≥4 FB ≥4 native replication log shipping (CDP substrate)

3.1 Mapping to Bacula levels

Mode Bacula Full Bacula Incremental Bacula Differential Footprint
dump gbak -b streaming always Full always Full zero staging
nbackup nbackup -B 0 (L0) nbackup -B N (vs last Incr) nbackup -B 1 (delta vs L0) only delta crosses the wire
replay gbak -b baseline + start log shipping continuous log archive snapshot + new log baseline log queue on disk

4. Supported Firebird versions

Firebird Status Notable features
2.5 Out of scope (gbak-only, no nbackup chain N>1, no replication — would force fallback throughout)
3.0 Full support nbackup chain L0..LN, encryption-at-rest, SuperServer threading
4.0 Full support + mode=replay Native replication log (CDP substrate), gbak -se services-mode
5.0 Full support + parallel backup gbak -par N parallel workers, profiler API, faster nbackup

4.1 Version detection

  • Probe via isql -z -q -i /dev/null (prints version line) or gbak -z.
  • Connect-time: query MON$DATABASE.MON$SERVER_VERSION.
  • Auto-enable gbak -par when FB ≥5 detected.
  • Auto-enable mode=replay only when FB ≥4 detected.
  • Refuses to start on FB ≤2.x with a clear message pointing at the matrix.

5. Architecture awareness — SuperServer / Classic / SuperClassic

Firebird has three distinct server architectures with opposing operational characteristics:

Arch Model Backup implication
SuperServer Single multi-threaded process, shared cache Default since FB 3; higher backup throughput than Classic
Classic Process per connection Pool exhaustion is real; the plugin throttles
SuperClassic Multi-threaded, per-attachment cache Hybrid; the plugin treats it as SuperServer

Detection via MON$ATTACHMENTS.MON$SERVER_PID cardinality + firebird.conf::ServerMode. On Classic, the plugin auto-throttles connections to avoid exhausting the pool on DBs with many active clients.

6. Cross-version migration

The plugin supports ODS (On-Disk Structure) upgrade during restore: a backup taken on FB 3 can be restored on FB 4 or FB 5. Typical path:

  1. Backup mode=dump on FB 3 (ODS 12.0).
  2. Customer migrates to FB 5 (ODS 13.1).
  3. Restore mode=dump targets the FB 5 server.
  4. gbak -r recognises the source ODS and upgrades it in-flight.

Not supported: downgrade (FB 5 → FB 3 would lose features).

7. Embedded Firebird — backup without a server running

For applications using embedded Firebird (single-file .fdb, no Firebird daemon running), mode=dump with embedded=true uses libfbembed to open the file directly. Typical use case: desktop apps, small ERPs, embedded devices.

8. Integrity verification

The backend runs gfix -v before and after each backup and smoke-queries RDB$RELATIONS. On corrupt DBs, gfix -v reports inconsistent pages — the plugin marks the job “warning” in Bacula (not fatal), generates a report, and proceeds.

9. Observability — optional Prometheus

The Prometheus sidecar exposes:

  • firebird_backup_duration_seconds{mode, db}
  • firebird_backup_bytes_total{mode, db}
  • firebird_nbackup_chain_depth{db} (gauge — alert if > 30)
  • firebird_replay_lag_seconds{db} (gauge — observed RPO)
  • firebird_gfix_warnings_total{db}

10. Documented anti-patterns

  • Don’t run mode=nbackup on DBs < 50 GB. Chain management overhead (lock file, level tracking) outweighs the gain. Use dump.
  • Don’t let the nbackup chain grow too deep. In-place restore must replay every level. Take a fresh Full (L0) every N=7-14 days.
  • Don’t run mode=replay on FB 3. Replication log is FB ≥4. The plugin refuses at runtime.
  • Don’t run parallel workers (gbak -par) on hardware with no idle cores. FB 5 parallel scales with free CPU; saturating it degrades live DB ops.
  • Don’t conflate crash-consistent with application-consistent. An FS snapshot of .fdb is crash-consistent — valid but may need gfix -v on restore. For application-consistent, use the dump/nbackup modes that talk to the engine.

11. License posture

Plugin ships under LicenseRef-PodHeitor-Proprietary. The backend is a standalone Rust binary, never touches the Bacula ABI.

Ready to evaluate?

Free 30-day trial for Firebird 3/4/5 servers. We guarantee at least 50% discount vs commercial alternatives (Bacula Enterprise doesn’t cover Firebird, Veeam doesn’t cover Firebird, Commvault has limited support). Exclusive support for the Brazilian Firebird ecosystem.

Heitor Faria — Founder, PodHeitor International
[email protected]
☎ +1 (789) 726-1749 · +55 (61) 98268-4220 (WhatsApp)
🔗 PodHeitor Firebird plugin page

Disponível em: pt-brPortuguês (Portuguese (Brazil))enEnglishesEspañol (Spanish)

Leave a Reply