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
gbakto a file + Bacula backup of the file (two steps, no coordination). - Manual
nbackupwith 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) orgbak -z. - Connect-time: query
MON$DATABASE.MON$SERVER_VERSION. - Auto-enable
gbak -parwhen FB ≥5 detected. - Auto-enable
mode=replayonly 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:
- Backup
mode=dumpon FB 3 (ODS 12.0). - Customer migrates to FB 5 (ODS 13.1).
- Restore
mode=dumptargets the FB 5 server. gbak -rrecognises 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=nbackupon DBs < 50 GB. Chain management overhead (lock file, level tracking) outweighs the gain. Usedump. - 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=replayon 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
.fdbis crash-consistent — valid but may needgfix -von 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:
Português (Portuguese (Brazil))
English
Español (Spanish)