Autor: Heitor Faria Contato: heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220 (WhatsApp) Versão: 1.0.0 — Disponibilidade Geral | Data: 2026-04-28 Licença: Copyright © 2026 Heitor Faria. Todos os direitos reservados.
AVISO COMERCIAL
Trazendo sua proposta de contratação ou renovação do Bacula Enterprise, Veeam, Commvault ou Netbackup? Oferecemos no mínimo 50% de desconto, com muito mais funcionalidades.
heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220 (WhatsApp)
Sumário
- Resumo Executivo
- Caso de Negócio
- Visão Geral da Arquitetura
- Análise Aprofundada dos Motores de Backup
- Capacidades de Replicação
- Segurança & Conformidade
- Observabilidade
- Guia de Instalação
- Referência de Configuração
- Procedimentos de Restauração & Casos de Uso
- Relatórios de Desempenho
- Matriz de Compatibilidade
- Guia de Dimensionamento
- Integração com Bacularis
- Migração do Bacula Enterprise
- Solução de Problemas
- Roadmap
- Evidências de Validação
1. Resumo Executivo
O PodHeitor Microsoft SQL Backup and Replication Plugin for Bacula é uma solução de proteção de dados para SQL Server pronta para produção e com suporte comercial, construída sobre o Bacula Community. Ele preenche uma lacuna crítica de mercado: empresas que utilizam Microsoft SQL Server e desejam a arquitetura de armazenamento comprovada do Bacula Community sem os custos e as limitações do Bacula Enterprise ou de alternativas proprietárias.
O Problema
Os administradores de bancos de dados SQL Server enfrentam um dilema difícil:
- Bacula Enterprise
mssql-fd.dllfunciona no Windows, mas custa significativamente mais, é limitado ao Windows, não possui paralelismo, compressão, replicação nem observabilidade. - Veeam, Commvault e NetBackup — os agentes SQL são caros, frequentemente exigem infraestrutura separada e prendem os clientes a formatos de armazenamento proprietários.
- Backup nativo do SQL Server (
BACKUP DATABASE TO DISK) não possui gerenciamento centralizado, políticas de retenção nem integração com armazenamento empresarial.
A Solução
PodHeitor MSSQL oferece:
| Capacidade | Valor para o Negócio |
|---|---|
| Paridade de recursos + extensões vs. Enterprise | Mesmo investimento, muito mais funcionalidades |
| Suporte a SQL Server no Linux | Protege a crescente base de SQL Server em Linux |
| 4× de throughput via I/O em stripes | Janelas de backup mais rápidas, menor RPO |
| 3 modos de replicação nativos | DR sem overhead de licenciamento do AG |
| Recuperação instantânea | RTO medido em minutos, não horas |
| Migração drop-in do Enterprise | Troca sem downtime, sem alterações no catálogo |
| Observabilidade com Prometheus + OTel | Dashboards Grafana, alertas, monitoramento de SLA |
| Compatível com TDE | Restauração de banco de dados criptografado entre servidores |
Validação (v1.0.0 GA)
E2E Test Suite (T01–T13, 16 scenarios): 16 / 16 PASS (3 consecutive runs)
OL9 unit/integration tests: 311 passed, 0 failed
Win2025 unit/integration tests: 381 passed, 0 failed
SQL Server tested: 2022 on Windows Server 2025
Always On AG: 2-node, CLUSTER_TYPE=NONE, SYNCHRONOUS_COMMIT
Bacula version: Community 15.0.3
Installed packages tested: RPM v1.0.0 (OL9) + zip v1.0.0 (Win2025)
2. Caso de Negócio
2.1 Comparativo de Custo Total de Propriedade
| Solução | Custo Relativo | SQL Linux | Replicação | Observabilidade | Throughput Máximo |
|---|---|---|---|---|---|
| Bacula Enterprise MSSQL plugin | $$$ | Não | Não | Não | 1× |
| Veeam for SQL Server | $$$$ | Limitado | Limitado | Básico | 1–2× |
| Commvault for SQL Server | $$$$$ | Sim | Sim | Sim | 1–2× |
| PodHeitor MSSQL | $ | Sim | Sim (3 modos) | Sim (completo) | 4× |
2.2 Principais Diferenciais
SQL Server no Linux — SQL Server 2017+ no Linux é agora mainstream. PodHeitor usa um motor nativo TDS/FIFO no Linux — sem proxy de agente Windows, sem compartilhamentos SMB, sem complexidade.
I/O Paralelo em Stripes — Um banco de dados de 1 TB que levaria 180 minutos com um único stream termina em 42 minutos com 8 stripes. Em ambientes VLDB, essa é a diferença entre cumprir ou não as janelas de backup.
Replicação Nativa via Bacula — Os volumes do Bacula já são duráveis, criptografados, replicados offsite e gerenciados por retenção. O motor de replicação PodHeitor os utiliza como transporte WAL entre instâncias SQL primária e secundária — sem infraestrutura de replicação separada.
Recuperação Instantânea — Em vez de aguardar horas para a restauração completa de um banco de dados de 2 TB, o mode=instant torna o banco de dados consultável em minutos ao montar o stream de backup com WITH MOVE. A restauração completa continua em segundo plano.
Migração Drop-In — O namespace byte-idêntico (@mssql/<INSTANCE>/<db>/data.bak) permite que backups existentes do Enterprise sejam restaurados pelo PodHeitor e vice-versa. Altere uma linha no bacula-fd.conf, execute um Full, pronto.
2.3 Quando Escolher PodHeitor
- Você usa Bacula Community e precisa de uma solução robusta de backup para SQL Server
- Você paga pelo Bacula Enterprise e quer reduzir custos sem perder funcionalidades
- Você roda SQL Server no Linux e precisa de um agente de backup nativo
- Você possui bancos VLDB (>500 GB) e precisa de janelas de backup mais rápidas
- Você precisa de DR sem a complexidade de licenciamento do AG Enterprise Edition
- Você usa Always On AG e quer preferência de backup + seeding automático de secundário
3. Visão Geral da Arquitetura
3.1 Design em Dois Níveis
┌─────────────────────────────────────────────────────────────────────┐
│ Bacula File Daemon │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ podheitor-mssql-fd.{dll,so} (pure Rust cdylib, v2.0.0+) │ │
│ │ - Built from ../PodHeitor Rust cdylib/crates/plugin-mssql/ │ │
│ │ - No Bacula AGPLv3 source statically linked │ │
│ │ - Implements Bacula FD plugin ABI v4 via metaplugin-rs │ │
│ │ - Spawns Rust backend as a subprocess │ │
│ │ - Proxies all I/O through PTCOMM binary protocol │ │
│ └─────────────────────────┬─────────────────────────────────────┘ │
└────────────────────────────│────────────────────────────────────────┘
│ stdin/stdout (PTCOMM binary frames)
│ stream IDs for parallel stripes
▼
┌─────────────────────────────────────────────────────────────────────┐
│ podheitor-mssql-backend (Rust binary) │
│ │
│ Engine Layer: vdi | tds_fifo | tds_url | snapshot │
│ Replication: logshipping | ag_bootstrap | fanout │
│ Orchestration: catalog | parallel striper | chain/integrity │
│ BI Servers: SSAS (XMLA) | SSRS | SSIS (SSISDB) │
│ Security: TDE capture/restore | Always Encrypted | ARD │
│ Observability: Prometheus /metrics | OpenTelemetry OTLP │
│ Cross-cutting: PTCOMM codec | Config | Logging | Compression │
└────────────────────────────┬────────────────────────────────────────┘
│ TDS / ODBC / COM VDI
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Microsoft SQL Server (Windows / Linux / Azure MI) │
│ msdb — LSN chain, backupset | sys.availability_* — AG topology │
└─────────────────────────────────────────────────────────────────────┘
3.2 Protocolo PTCOMM
PTCOMM é um protocolo binário leve de enquadramento — a camada de comunicação entre o carregador Rust cdylib dentro do FD e o subprocess Rust backend independente:
| Frame | Byte | Finalidade |
|---|---|---|
| Data | D |
Bloco de dados de backup (com ID de stream para N stripes) |
| Command | C |
Solicitação de operação |
| File | F |
Limite de início/fim de arquivo |
| Info | I |
Mensagem de progresso para o log do job Bacula |
| Error | E |
Fatal — abortar job |
| Warning | W |
Aviso não-fatal |
| Terminate | T |
Encerramento normal da sessão |
Os IDs de stream permitem que N stripes paralelos sejam multiplexados sobre um único par stdin/stdout. O Bacula FD enxerga N arquivos separados.
3.3 Seleção Automática de Motor
mode=auto (default)
├── Windows? → mode=vdi (IClientVirtualDevice COM API)
├── Linux? → mode=tds_fifo (TDS + POSIX FIFO)
└── Azure MI? → mode=tds_url (BACKUP TO URL embedded S3)
Explicit override: mode=snapshot | mode=replicate_logshipping | ...
3.4 Modelo de Estado
Estado do diretório de trabalho (/opt/bacula/working/mssql-state/):
- Cache da cadeia LSN — último LSN aplicado por banco de dados (integridade diferencial/log)
- Estado do follower — último LSN aplicado na replicação por banco de dados
- Manifesto de backup — layout do banco de dados, compressão, contagem de stripes para restauração
- Tokens de recuperação — retomada do job após interrupção
Footprint total: < 10 MB por instância SQL. Zero staging — nenhum arquivo .bak é gravado em disco.
4. Análise Aprofundada dos Motores de Backup
4.1 Motor VDI (Windows)
Tecnologia: Microsoft Virtual Device Interface — API COM IClientVirtualDevice (sqlvdi.dll), implementada via vtables COM escritas manualmente com windows-sys em Rust.
Modelo de threading (por banco de dados, por stripe):
Thread A: ODBC → BACKUP DATABASE [db] TO VIRTUAL_DEVICE='...' (blocks on SQL I/O)
Thread B: VDI pump → GetCommand() → Write/Flush → CompleteCommand (pulls buffers)
Thread C: PTCOMM encoder → bounded channel(8) back-pressure → stdout → Bacula
Limite de memória: stripes × parallel_dbs × 8 × maxtransfersize
- Padrão (1 stripe, 1 BD, 64 KB): 512 KB
- VLDB (8 stripes, 4 BDs, 4 MB): 1 GB — ajuste
maxtransfersizeconforme necessário
Sequência de backup:
- Conexão ODBC + catálogo do banco de dados (filtros de inclusão/exclusão/modelo de recuperação)
CreateEx(N devices)para contagem de stripes- Emitir
BACKUP DATABASE WITH BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE, COMPRESSION, CHECKSUM, [DIFFERENTIAL|COPY_ONLY] - VDI pump → stream PTCOMM → Bacula FD
- Consultar
msdb.backupsetpara LSN (FirstLSN, LastLSN) após conclusão - Emitir sidecar
__ph_manifest.json(cadeia LSN, estatísticas de compressão)
4.2 Motor TDS/FIFO (Linux)
Tecnologia: tiberius (cliente TDS 7.x assíncrono em Rust puro) + named pipes POSIX.
Fluxo:
tokio runtime
├── TDS session: BACKUP DATABASE [db] TO DISK='/fifo/job-0.fifo', '/fifo/job-1.fifo'...
├── Async FIFO reader [stripe 0] → decode → PTCOMM stream 0 → Bacula
├── Async FIFO reader [stripe 1] → decode → PTCOMM stream 1 → Bacula
└── ...
SQL Server writes to FIFOs concurrently on its I/O threads
Plugin readers drain asynchronously → near-zero kernel overhead
Ciclo de vida do FIFO: Criado com modo 0600 em diretório por job. Limpo na saída e no SIGTERM. Suportado por tmpfs quando disponível.
4.3 Motor TDS URL (Azure MI / SQL Server 2022)
Servidor HTTPS Hyper 1.x embutido → CREATE CREDENTIAL + BACKUP TO URL='https://127.0.0.1:<port>/...' → SQL PUT-streams → demux → PTCOMM. Credencial removida após o job. Funciona para Azure SQL MI (sem filesystem) e integração S3 do SQL 2022.
4.4 Motores de Snapshot
VSS (Windows): IVssBackupComponents → quiesce do writer SQL → DoSnapshotSet → montar somente leitura → transmitir MDF/NDF/LDF → DeleteSnapshot.
LVM (Linux): Quiesce SQL → lvcreate --snapshot → montar somente leitura → transmitir arquivos → lvremove.
ZFS: Quiesce SQL → zfs snapshot → acessar .zfs/snapshot/ → transmitir arquivos → zfs destroy.
NetApp ONTAP: Adiado para v1.1 — atualmente retorna erro acionável com ETA da v1.1.
5. Capacidades de Replicação
PodHeitor implementa três modos de replicação do SQL Server usando volumes Bacula como transporte WAL. Nenhuma infraestrutura de replicação separada é necessária.
5.1 Log Shipping
PRIMARY SQL (primary-fd plugin)
→ BACKUP LOG → Bacula volume (every 5 min Incremental job)
SECONDARY SQL (follower-fd plugin)
→ bconsole query: find latest log job for target DB
→ Download log backup
→ RESTORE LOG [db] WITH STANDBY='/standby_undo.bak'
→ DB online read-only (STANDBY mode)
RPO: 30 seg – 15 min. RTO: Minutos (secundário sempre em STANDBY/NORECOVERY).
5.2 AG Bootstrap
Provisiona nova réplica do AG a partir da cadeia Bacula sem tocar no primário: Full → Diff → Logs (WITH NORECOVERY) → ALTER DATABASE SET HADR AVAILABILITY GROUP.
5.3 Fanout (1→N Regiões)
Cadeia de backup primário única consumida por N instâncias de FD secundárias (São Paulo → US East → EU West). Zero carga adicional de SQL no primário. Convergência dentro de 2× o intervalo de log.
5.4 Máquina de Estado do Follower
O estado persistente garante idempotência (reaplicar um log já aplicado é uma operação sem efeito), detecção de lacunas (aciona alerta + fallback para ressemeadura Full) e recuperação de falha (retoma a partir do último LSN aplicado).
6. Segurança & Conformidade
6.1 Gerenciamento de Credenciais
# Recomendado: passfile (permissões de arquivo aplicadas)
passfile = /opt/bacula/etc/.mssql_pass # mode 0640, warn if world-readable
# Inline (auto-redacted everywhere in logs)
password = <secret> # → appears as "password=<REDACTED>" in all output
6.2 Ciclo de Vida do Certificado TDE
tde_capture=yes:
- Exportar certificado DEK + PVK criptografada via T-SQL → criptografar com chave derivada do job → transportar via PTCOMM RestoreObject (nunca toca o filesystem)
tde_restore_cert=AUTO na restauração:
- Buscar do RestoreObject →
CREATE MASTER KEY(se não existir) →CREATE CERTIFICATE FROM BINARY→RESTORE DATABASE WITH MOVE
Restauração TDE cross-server totalmente automatizada. Sem exportação/importação manual de certificado.
6.3 Segurança de Transporte
| Conexão | Criptografia |
|---|---|
| TDS (não-localhost) | TLS 1.2+ exigido por padrão |
| Azure MI | TLS sempre aplicado |
| PTCOMM (backend↔adaptador) | Pipe de processo do SO (mesmo host, isolado pelo SO) |
| Endpoint de métricas | HTTP somente no loopback |
6.4 Permissões Mínimas de SQL
CREATE LOGIN [bacula_backup] WITH PASSWORD = '<strong_password>';
GRANT BACKUP DATABASE, BACKUP LOG, VIEW SERVER STATE TO [bacula_backup];
-- For TDE capture:
GRANT CONTROL SERVER TO [bacula_backup];
-- For system DBs: BACKUP DATABASE on master, msdb, model
6.5 Hook Antiransomware
ransomware_hook=yes → consulta pré-backup ao daemon PodHeitor ARD → anomalia reportada → job abortado com frame de erro. Evita realizar backup de dados já comprometidos por ransomware.
6.6 Integridade do Release
sha256sum -c releases/SHA256SUMS --ignore-missing
rpm --checksig podheitor-mssql-plugin-1.0.0-1.el9.x86_64.rpm
7. Observabilidade
7.1 Métricas Prometheus
Habilitar: metrics_endpoint=0.0.0.0:9200
podheitor_mssql_jobs_started_total{instance,db}
podheitor_mssql_jobs_succeeded_total{instance,db}
podheitor_mssql_jobs_failed_total{instance,db}
podheitor_mssql_bytes_backed_up_total{instance,db}
podheitor_mssql_last_job_duration_ms{instance,db}
podheitor_mssql_last_backup_size_bytes{instance,db,level}
podheitor_mssql_replication_lag_seconds{db,role}
podheitor_mssql_dbs_backed_up_total
Verificação de saúde: GET /healthz → 200 OK {"status":"ok","version":"1.0.0"}
7.2 Rastreamentos OpenTelemetry
Habilitar: otel_endpoint=http://otel-collector:4318
Cada job produz spans aninhados: backup_job → catalog_query → backup_db por banco de dados → vdi_stripe por stripe → verifyonly. Compatível com Jaeger, Zipkin, Tempo, AWS X-Ray, Azure Monitor.
8. Guia de Instalação
8.1 Pré-requisitos do SQL Server
-- Create backup login
CREATE LOGIN [bacula_backup] WITH PASSWORD = '<strong_password>';
GRANT BACKUP DATABASE, BACKUP LOG, VIEW SERVER STATE TO [bacula_backup];
-- passfile (Linux)
echo '<password>' > /opt/bacula/etc/.mssql_pass
chown root:bacula /opt/bacula/etc/.mssql_pass && chmod 640 /opt/bacula/etc/.mssql_pass
Microsoft ODBC Driver 18 (Linux):
curl -fsSL https://packages.microsoft.com/config/rhel/9/prod.repo | tee /etc/yum.repos.d/mssql-release.repo
ACCEPT_EULA=Y dnf install -y msodbcsql18 unixODBC
8.2 Instalação RPM no Linux
# Verify SHA256
sha256sum -c SHA256SUMS --ignore-missing
# Install
rpm -Uvh podheitor-mssql-plugin-1.0.0-1.el9.x86_64.rpm
# → /opt/bacula/plugins/podheitor-mssql-fd.so
# → /opt/bacula/bin/podheitor-mssql-backend
# → /opt/bacula/etc/podheitor-mssql.conf (from .sample if absent)
# Edit config and reload FD (done automatically by %post)
vi /opt/bacula/etc/podheitor-mssql.conf
systemctl reload bacula-fd
# Verify
/opt/bacula/bin/podheitor-mssql-backend --version
# → PodHeitor MSSQL Backend v1.0.0
8.3 Instalação via zip no Windows
Expand-Archive podheitor-mssql-plugin-1.0.0-win64.zip -DestinationPath C:ph-install
Copy-Item C:ph-installpodheitor-mssql-fd.dll "C:Program FilesBaculaplugins"
Copy-Item C:ph-installpodheitor-mssql-backend.exe "C:Program FilesBaculabin"
Copy-Item C:ph-installpodheitor-mssql.conf.sample "C:ProgramDataBaculaetcpodheitor-mssql.conf"
net stop bacula-fd && net start bacula-fd
& "C:Program FilesBaculabinpodheitor-mssql-backend.exe" --version
8.4 Jobs do Bacula Director
Job {
Name = "MSSQL-Full"
Type = Backup; Level = Full
Client = mssql-server-fd
FileSet = "MSSQL-Production"
Schedule = "WeeklyCycle"
Storage = File1; Pool = Full
}
Job {
Name = "MSSQL-Diff"
Type = Backup; Level = Differential
Client = mssql-server-fd
FileSet = "MSSQL-Production"
Schedule = "DailyCycle"
Storage = File1; Pool = Differential
}
Job {
Name = "MSSQL-Log"
Type = Backup; Level = Incremental
Client = mssql-server-fd
FileSet = "MSSQL-Production"
Schedule = "HourlyCycle"
Storage = File1; Pool = Incremental
}
9. Referência de Configuração
9.1 Arquivo de Configuração
# /opt/bacula/etc/podheitor-mssql.conf
user = bacula_backup
passfile = /opt/bacula/etc/.mssql_pass
authtype = server
checksum = yes
compress = native+zstd
compress_level = 3
metrics_endpoint = 0.0.0.0:9200
9.2 Exemplos de FileSet
Todos os bancos de dados, VDI, verificação de integridade:
FileSet {
Name = "MSSQL-Production"
Enable VSS = no
Include {
Options { Signature = SHA256 }
Plugin = "podheitor-mssql: checksum=yes verify_backup=yes compress=native+zstd include_server_objects=yes tde_capture=yes"
}
}
Linux, 4 stripes, bancos de dados específicos:
FileSet {
Name = "MSSQL-Linux"
Include {
Options { Signature = SHA256 }
Plugin = "podheitor-mssql: mode=tds_fifo include=prod_orders include=prod_inventory stripes=4 compress=native+zstd passfile=/opt/bacula/etc/.mssql_pass"
}
}
VLDB 8 stripes:
FileSet {
Name = "MSSQL-VLDB"
Include {
Options { Signature = SHA256 }
Plugin = "podheitor-mssql: database=data_warehouse stripes=8 parallel_dbs=1 compress=native+zstd buffercount=32 maxtransfersize=4194304 verify_backup=yes"
}
}
Always On AG, backup da réplica secundária legível:
FileSet {
Name = "MSSQL-AG"
Enable VSS = no
Include {
Options { Signature = SHA256 }
Plugin = "podheitor-mssql: ag_preference=readable_secondary ag_failover_retry=3 copyonly tde_capture=yes"
}
}
9.3 Opções Completas de Backup
| # | Opção | Padrão | Descrição |
|---|---|---|---|
| 1 | database |
* |
Glob de BD (todos exceto tempdb) |
| 2 | include |
— | Inclusão explícita (múltipla) |
| 3 | exclude |
tempdb |
Glob de exclusão (múltiplo) |
| 4 | user |
— | Login SQL |
| 5 | domain |
— | Domínio AD |
| 6 | password |
— | Senha inline (auto-redacted) |
| 7 | passfile |
— | Caminho do arquivo de senha |
| 8 | authtype |
windows |
windows / server / azure_ad / managed_identity |
| 9 | instance |
MSSQLSERVER |
Nome da instância (múltiplo) |
| 10 | all_instances |
off | Auto-descobrir todas as instâncias |
| 11 | hostname |
(local) |
String de servidor ODBC |
| 12 | abort_on_error |
off | Falhar o job em qualquer erro de BD |
| 13 | copyonly |
off | COPY_ONLY: yes=todos, incremental=somente logs |
| 14 | fullbackup |
off | Forçar Full independente do nível Bacula |
| 15 | skipreadonly |
off | Ignorar BDs somente leitura no Incremental |
| 16 | dblayout |
off | Armazenar layout do BD como RestoreObject |
| 17 | lock_timeout |
0 ms |
SET LOCK_TIMEOUT |
| 18 | buffercount |
10 |
Contagem de buffers de I/O VDI |
| 19 | blocksize |
65536 |
Tamanho do bloco físico (bytes) |
| 20 | maxtransfersize |
65536 |
Transferência VDI máxima (bytes) |
| 21 | connection_string |
— | Sobrescrever string de conexão ODBC |
| 22 | checksum |
yes |
WITH CHECKSUM |
| 23 | driver |
ODBC 18 | Nome do driver ODBC |
| 24 | target_backup_recovery_models |
all | Filtro: SIMPLE, FULL, BULK_LOGGED |
| 25 | simple_recovery_models_incremental_action |
make_full |
make_full / ignore_with_error / ignore |
| 26 | mode |
auto |
Motor: auto,vdi,tds_fifo,tds_url,snapshot,replicate_* |
| 27 | stripes |
1 |
Stripes paralelos (1–64) |
| 28 | parallel_dbs |
núcleos de CPU | Máximo de backups de BD simultâneos |
| 29 | compress |
native+zstd |
none,native,zstd,lz4,native+zstd |
| 30 | compress_level |
3 |
1–22 (zstd), 1–9 (gzip) |
| 31 | max_rate_kbps |
0 |
Limitação de banda (0=ilimitado) |
| 32 | resource_governor_classifier |
— | Classificador SQL Resource Governor |
| 33 | page_verify |
none |
none,page_audit,torn_page |
| 34 | verify_backup |
no |
RESTORE VERIFYONLY após backup |
| 35 | dbcc_checkdb |
no |
no,physical_only,full |
| 36 | ag_preference |
auto |
auto,primary,secondary,readable_secondary |
| 37 | ag_failover_retry |
3 |
Tentativas em failover do AG durante o job |
| 38 | tde_capture |
no |
Capturar certificados TDE como RestoreObject |
| 39 | always_encrypted_cmk_report |
no |
Snapshot de metadados CMK |
| 40 | include_system_dbs |
master,msdb,model |
Controle granular de BDs de sistema |
| 41 | include_server_objects |
no |
Exportar logins, linked servers, jobs |
| 42 | include_filestream |
yes |
Consistência FILESTREAM/FileTable |
| 43 | include_hekaton_xtp |
yes |
Arquivos de checkpoint In-Memory OLTP |
| 44 | include_service_broker |
no |
Exportação de fila do Service Broker |
| 45 | include_ssas |
no |
Servidores SSAS para backup XMLA |
| 46 | include_ssrs |
no |
SSRS host:port |
| 47 | include_ssis |
no |
SSISDB + master key |
| 48 | url_endpoint |
— | URL S3/Azure para mode=tds_url |
| 49 | url_credential |
— | Token SAS ou identidade MI |
| 50 | snapshot_provider |
plataforma | vss,lvm,zfs |
| 51 | dry_run |
no |
Validação preflight, sem gravação |
| 52 | ransomware_hook |
no |
Abortar em anomalia ARD |
| 53 | metrics_endpoint |
— | Prometheus /metrics host:port |
| 54 | otel_endpoint |
— | URI de traces OTLP |
| 55 | use_sudo |
no |
Elevar para gerenciamento de FIFO no Linux |
| 56 | cluster_id |
— | Prefixo de namespace multi-cluster |
| 57 | config_file |
padrão da plataforma | Caminho do arquivo de configuração externo |
| 58 | virtual_full |
no |
Full sintético a partir da cadeia |
9.4 Opções Completas de Restauração
| # | Opção | Padrão | Descrição |
|---|---|---|---|
| 1 | instance |
MSSQLSERVER |
Instância SQL de destino |
| 2 | database |
nome de origem | Nome do novo banco de dados |
| 3 | username |
— | Login SQL |
| 4 | password |
— | Senha |
| 5 | domain |
— | Domínio AD |
| 6 | hostname |
(local) |
Servidor de destino |
| 7 | authtype |
windows |
Modo de autenticação |
| 8 | recovery |
yes |
WITH RECOVERY (no=NORECOVERY) |
| 9 | stop_before_mark |
— | STOPBEFOREMARK 'mark' |
| 10 | stop_at_mark |
— | STOPATMARK 'mark' |
| 11 | stop_at |
— | STOPAT 'datetime' |
| 12 | restricted_user |
no |
WITH RESTRICT_USER |
| 13 | verify |
off | Verificar antes de restaurar |
| 14 | connection_string |
— | Sobrescrever ODBC |
| 15 | checksum |
no |
WITH CHECKSUM na restauração |
| 16 | driver |
ODBC 18 | Driver ODBC |
| 17 | mode |
auto |
auto,instant,in_place,new_db,to_disk,single_item,ag_reseed,master_restore |
| 18 | stripes |
valor do backup | Deve coincidir com os stripes do backup |
| 19 | dbcc_checkdb |
physical_only |
DBCC após restauração |
| 20 | row_count_compare |
no |
Comparar contagens de linhas com o manifesto |
| 21 | single_item_target |
— | schema.table[,...] |
| 22 | sandbox_docker_image |
mssql/server:2022 | Imagem Docker de sandbox |
| 23 | ag_target_group |
— | Nome do AG para ag_reseed |
| 24 | file_relocation_map |
— | Mapa JSON {logical: physical} |
| 25 | tde_restore_cert |
— | Pacote de certificado TDE (AUTO=do RestoreObject) |
| 26 | drop_existing |
no |
no,yes,only_if_match |
| 27 | tail_log_before |
no |
tail-log automático antes de restauração destrutiva |
| 28 | point_in_time_tz |
UTC |
Fuso horário para stop_at |
| 29 | parallel_restore_dbs |
núcleos de CPU | Restaurações de BD simultâneas |
| 30 | progress_report_interval |
30 s |
Cadência de progresso no log do job |
| 31 | regexwhere |
— | Regex de realocação de arquivo Bacula |
10. Procedimentos de Restauração & Casos de Uso
10.1 Restauração Padrão no Local
# bconsole restore
Plugin Options: instance=MSSQLSERVER database=AdventureWorks recovery=yes
10.2 Restauração Point-in-Time
Plugin Options: stop_at=2026-04-28T10:30:00 database=AdventureWorks_pit recovery=yes
Plugin Options: stop_at_mark=SavePoint1 database=AdventureWorks_pit recovery=yes
10.3 Renomear + Realocação de Arquivo
// file_relocation.json
{
"AdventureWorks_Data": "D:NewDataAdventureWorks.mdf",
"AdventureWorks_Log": "L:NewLogsAdventureWorks_log.ldf"
}
Plugin Options: database=AdventureWorks_new file_relocation_map=C:relocation.json
10.4 Recuperação Instantânea
Plugin Options: mode=instant database=AdventureWorks_instant
# → BD consultável em ~35 seg (exemplo de 100 GB)
# → Restauração completa continua em segundo plano
10.5 Restauração de Item Único (Tabela)
Plugin Options: mode=single_item single_item_target=dbo.Orders,dbo.OrderItems database=recovery_sandbox
# → Container Docker SQL efêmero
# → Restauração completa para o container
# → Extração de tabela via bcp → scripts INSERT / CSV
# → Container removido após extração
10.6 AG Reseed (Secundário Perdido)
Plugin Options: mode=ag_reseed ag_target_group=AG_Production database=prod_orders tail_log_before=yes recovery=no
# → Backup tail-log → Remover do AG → Restaurar Full+Diff+Logs → Reintegrar ao AG
10.7 Restauração TDE Cross-Server
Plugin Options: tde_restore_cert=AUTO database=SecureDB
# → Certificado buscado do RestoreObject → instalado → RESTORE DATABASE WITH MOVE
11. Relatórios de Desempenho
11.1 Throughput por Tamanho de BD e Contagem de Stripes
Ambiente: SQL Server 2022 / Win Server 2025 / 16 núcleos / NVMe / 10 Gbps para Bacula
| Tamanho do BD | stripes=1 | stripes=2 | stripes=4 | stripes=8 |
|---|---|---|---|---|
| 10 GB | 52 s | 30 s | 18 s | 15 s |
| 100 GB | 8,0 min | 4,7 min | 2,8 min | 2,2 min |
| 1 TB | 180 min | 100 min | 60 min | 42 min |
11.2 Taxas de Compressão
| Tipo de BD | none | native | native+zstd |
|---|---|---|---|
| OLTP (AdventureWorks) | 1× | 3,1× | 3,8× |
| Data Warehouse | 1× | 4,2× | 5,0× |
| Intensivo em JSON | 1× | 1,8× | 2,7× |
11.3 Desempenho de Restauração
| Tamanho do BD | Padrão | Instantânea (consultável em) |
|---|---|---|
| 10 GB | 45 s | 8 s |
| 100 GB | 11 min | 35 s |
| 1 TB | 75 min | 3 min |
11.4 Validação E2E (v1.0.0 GA — Execução 9)
PASS: 16 / 16 FAIL: 0 / 16
Duration: 22:01 to 22:13 (12 minutes, installed packages)
Environment: Bacula 15.0.3 + SQL Server 2022 + 2-node AG
12. Matriz de Compatibilidade
Versões do SQL Server
| Versão | Windows VDI | Linux TDS/FIFO | Azure MI | Always On |
|---|---|---|---|---|
| 2012, 2014 | ✅ | — | — | ✅ Básico |
| 2016, 2017 | ✅ | ✅ | — | ✅ |
| 2019, 2022 | ✅ | ✅ | ✅ | ✅ |
| Azure SQL MI | — | — | ✅ | ✅ Auto |
Versões do Bacula Community
| Versão | Status |
|---|---|
| 14.0.x | Compatível |
| 15.0.x | ✅ Testado e certificado |
13. Guia de Dimensionamento
Host do File Daemon
| Carga de Trabalho | RAM | CPU | Rede |
|---|---|---|---|
| Pequeno (< 100 GB) | 1 GB | 2 núcleos | 1 Gbps |
| Médio (100 GB–1 TB) | 4 GB | 4 núcleos | 1 Gbps |
| Grande (1–10 TB) | 8 GB | 8 núcleos | 10 Gbps |
| VLDB (> 10 TB) | 16 GB | 16 núcleos | 10 Gbps+ |
Fórmula de memória: parallel_dbs × stripes × buffercount × maxtransfersize
Padrão: 1 × 1 × 10 × 64 KB = 640 KB VLDB: 4 × 8 × 32 × 4 MB = 4 GB
Impacto no SQL Server
| Configuração | CPU | I/O | Recomendação |
|---|---|---|---|
compress=native+zstd |
+8–20% | −72% | Padrão — fortemente recomendado |
stripes=4 |
SQL paralelo | +4× IOPS | Padrão para VLDB |
dbcc_checkdb=physical_only |
+10–30% | +30% | Agendamento semanal |
resource_governor_classifier |
Limitado por política | Limitado por política | Hosts OLTP |
14. Integração com Bacularis
Schemas de RestoreObject
mssql-dblayout.json (emitido com dblayout=yes):
{
"schema_version": "1.0",
"instance": "MSSQLSERVER",
"databases": [{
"name": "AdventureWorks",
"level": "Full",
"compressed_bytes": 82000000,
"original_bytes": 256000000,
"first_lsn": "34000000001234500001",
"last_lsn": "34000000012345600001",
"recovery_model": "FULL",
"stripes": 4,
"compression": "native+zstd",
"files": [
{"logical": "AdventureWorks_Data", "physical": "C:DataAW.mdf", "size_bytes": 230000000},
{"logical": "AdventureWorks_Log", "physical": "C:LogAW_log.ldf", "size_bytes": 26000000}
]
}]
}
mssql-tde-{db}.json (emitido com tde_capture=yes):
{
"schema_version": "1.0",
"database": "SecureDB",
"certificate_name": "SecureDB_Cert",
"certificate_der_b64": "<base64>",
"encrypted_pvk_b64": "<base64>"
}
Acesso via bconsole
list restoreobjects jobid=5123
llist restoreobject jobid=5123 objectname=mssql-dblayout.json
15. Migração do Bacula Enterprise
15.1 Promessa de Compatibilidade
Namespace byte-idêntico. Backups do Enterprise são 100% restauráveis pelo PodHeitor e vice-versa.
15.2 Procedimento Sem Downtime
Dia 1: Instalar PodHeitor junto ao Enterprise (ambos presentes no FD)
Dia 1: dry_run=yes → validar conectividade + permissões
Dia 2: Primeiro backup Full com PodHeitor → verificar no log do Bacula
Dia 3: Alterar FileSet: "mssql:" → "podheitor-mssql:"
Dia 30+: Remover plugin Enterprise após ciclo de retenção (opcional)
15.3 Diferenças Notáveis
| Aspecto | Enterprise | PodHeitor |
|---|---|---|
checksum padrão |
Não |
Sim (mais seguro) |
| Compressão padrão | Nenhuma | native+zstd (backups menores) |
| Nome do arquivo Differential | data.bak |
data.diff.bak (distinguível, ambos reconhecidos) |
Sidecars __ph_* |
Não produzidos | Produzidos (Enterprise ignora na restauração) |
16. Solução de Problemas
16.1 Modos de Diagnóstico
# Preflight (sem gravação)
Plugin = "podheitor-mssql: dry_run=yes"
# VDI tracing (Windows)
set PODHEITOR_VDI_DEBUG=1 # then restart FD + run job
# Backend info
/opt/bacula/bin/podheitor-mssql-backend --version --features
16.2 Tabela de Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
Login failed for user |
Credenciais incorretas ou authtype errado | Verificar user/passfile/authtype |
VD_E_ABORT |
VDI encerrada pelo SQL | Verificar log de erros SQL; aumentar maxtransfersize |
PTCOMM header bad length |
Saída stdout inesperada | Verificar variáveis de ambiente de debug ODBC |
Cannot find master key |
Captura TDE sem master key | CREATE MASTER KEY ENCRYPTION BY PASSWORD |
AG replica not preferred |
ag_preference não satisfeita | Definir ag_preference=primary temporariamente |
Address already in use |
Conflito de porta de métricas | Alterar porta de metrics_endpoint |
FIFO permission denied |
Não está no grupo mssql | usermod -aG mssql bacula ou use_sudo=yes |
RESTORE VERIFYONLY failed |
Corrupção de backup/mídia | Investigar com DBCC |
16.3 Localizações dos Logs
| Log | Linux | Windows |
|---|---|---|
| Bacula FD | /opt/bacula/log/bacula-fd.log |
Log de Eventos do Windows |
| Backend PodHeitor | /opt/bacula/log/podheitor-mssql-<jobid>.log |
%PROGRAMDATA%Baculalog |
| SQL Server | /var/opt/mssql/log/errorlog |
Log de Eventos do Windows |
17. Roadmap
| Versão | ETA | Destaques |
|---|---|---|
| v1.0.0 GA | 2026-04-28 | Todos os F0–F10. 16/16 E2E PASS. |
| v1.1 | Q3 2026 | Linux ARM64, pacote DEB, instalador NSIS, NetApp ONTAP |
| v1.2 | Q4 2026 | Sidecar Kubernetes (Helm chart) |
| v1.3 | Q1 2027 | Backup do Query Store, Extended Events |
| v1.4 | Q2 2027 | Descritor completo de plugin na UI do Bacularis |
| v1.5 | Q3 2027 | Replicação cross-version (2019→2022) |
18. Evidências de Validação
Resultados dos Testes E2E (Execução 9 — Pacotes Instalados)
[22:01:XX] ✓ PASS: T01-Full-backup
[22:02:XX] ✓ PASS: T02-Diff-backup
[22:03:XX] ✓ PASS: T03-Log-backup
[22:04:XX] ✓ PASS: T04-Restore-inplace
[22:05:XX] ✓ PASS: T05-Restore-new-db
[22:06:XX] ✓ PASS: T06-Compressed-backup
[22:07:XX] ✓ PASS: T07-Verify-backup
[22:08:XX] ✓ PASS: T08-MultiDB-backup
[22:08:XX] ✓ PASS: T09-Instant-restore
[22:08:XX] ✓ PASS: T10-Replicate-Primary-Full
[22:08:XX] ✓ PASS: T10b-Replicate-Primary-Log
[22:09:XX] ✓ PASS: T11-Replicate-Follower-Apply
[22:09:XX] ✓ PASS: T11b-Follower-Idempotency
[22:13:XX] ✓ PASS: T11c-RPO-Simulation
[22:13:XX] ✓ PASS: T12-AG-Bootstrap
[22:13:XX] ✓ PASS: T13-Fanout-Primary-Full
PASS: 16 / 16 | FAIL: 0 / 16
Resultados dos Testes Cargo
OL9: test result: ok. 311 passed; 0 failed
Win2025: test result: ok. 381 passed; 0 failed
Artefatos do Release
podheitor-mssql-plugin-1.0.0-1.el9.x86_64.rpm (562 KB)
SHA256: 4b785ae74e6e9a5151eb9b10304daae8daf9402888cce6ae5459533b668e809d
podheitor-mssql-plugin-1.0.0-win64.zip (772 KB)
SHA256: 33a6883df08f52ab8f881d70f1efa1760d753dc09067da8f19476bdfa1de2973
Contato & Licenciamento
Autor: Heitor Faria | E-mail: heitor@opentechs.lat Telefone: +1 786 726-1749 | WhatsApp: +55 61 98268-4220
Copyright © 2026 Heitor Faria. Todos os direitos reservados. Proprietário e confidencial. Licenciamento comercial disponível.
Trazendo sua proposta do Bacula Enterprise, Veeam, Commvault ou Netbackup? Mínimo 50% de desconto + muito mais funcionalidades. heitor@opentechs.lat | +1 786 726-1749 | +55 61 98268-4220
Disponível em:
Português
English (Inglês)
Español (Espanhol)