Respaldo SQL Server enterprise vía VDI. Full / Differential / Log con PITR al milisegundo, soporte Always On AG, FileStream y bases multi-terabyte sin ventana.
- VDI (Virtual Device Interface) — streaming directo, sin archivo intermedio en disco.
- PITR al milisegundo — restauración precisa vía transaction log chain.
- Always On AG-aware — respaldo desde secondary readable, sin overhead en primary.
- FileStream y FileTable — captura inline, sin export manual.
- Backup comprimido nativo — combina compresión SQL con zstd PodHeitor.
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 →
Tabla de Contenidos
- Resumen Ejecutivo
- Caso de Negocio
- Descripción General de la Arquitectura
- Análisis en Profundidad de los Motores de Backup
- Capacidades de Replicación
- Seguridad & Cumplimiento
- Observabilidad
- Guía de Instalación
- Referencia de Configuración
- Procedimientos de Restauración & Casos de Uso
- Informes de Rendimiento
- Matriz de Compatibilidad
- Guía de Dimensionamiento
- Integración con Bacularis
- Migración desde Bacula Enterprise
- Solución de Problemas
- Roadmap
- Evidencias de Validación
1. Resumen Ejecutivo
El PodHeitor Microsoft SQL Backup and Replication Plugin for Bacula es una solución de protección de datos para SQL Server lista para producción y con soporte comercial, construida sobre PodHeitor Backup. Cubre una brecha crítica del mercado: empresas que utilizan Microsoft SQL Server y desean la arquitectura de almacenamiento probada de PodHeitor Backup sin los costos y las limitaciones de Bacula Enterprise o de alternativas propietarias.
El Problema
Los administradores de bases de datos SQL Server enfrentan un difícil dilema:
- Bacula Enterprise
mssql-fd.dllfunciona en Windows, pero tiene un costo significativamente mayor, está limitado a Windows, no tiene paralelismo, compresión, replicación ni observabilidad. - Veeam, Commvault y NetBackup — los agentes SQL son costosos, frecuentemente requieren infraestructura separada y atan a los clientes a formatos de almacenamiento propietarios.
- El backup nativo de SQL Server (
BACKUP DATABASE TO DISK) no tiene gestión centralizada, políticas de retención ni integración con almacenamiento empresarial.
La Solución
PodHeitor MSSQL ofrece:
| Capacidad | Valor para el Negocio |
|---|---|
| Paridad de características + extensiones vs. Enterprise | La misma inversión, muchas más funcionalidades |
| Soporte a SQL Server en Linux | Protege la creciente base de SQL Server en Linux |
| 4× de throughput mediante I/O en stripes | Ventanas de backup más rápidas, menor RPO |
| 3 modos de replicación nativos | DR sin sobrecosto de licenciamiento del AG |
| Recuperación instantánea | RTO medido en minutos, no en horas |
| Migración drop-in desde Enterprise | Cambio sin tiempo de inactividad, sin cambios en el catálogo |
| Observabilidad con Prometheus + OTel | Dashboards Grafana, alertas, monitoreo de SLA |
| Compatible con TDE | Restauración de base de datos cifrada entre servidores |
Validación (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 Negocio
2.1 Comparación de Costo Total de Propiedad
| Solución | Costo Relativo | SQL Linux | Replicación | Observabilidad | Throughput Máximo |
|---|---|---|---|---|---|
| Bacula Enterprise MSSQL plugin | $$$ | No | No | No | 1× |
| Veeam for SQL Server | $$$$ | Limitado | Limitado | Básico | 1–2× |
| Commvault for SQL Server | $$$$$ | Sí | Sí | Sí | 1–2× |
| PodHeitor MSSQL | $ | Sí | Sí (3 modos) | Sí (completo) | 4× |
2.2 Principales Diferenciadores
SQL Server en Linux — SQL Server 2017+ en Linux es ya una solución madura y ampliamente adoptada. PodHeitor utiliza un motor nativo TDS/FIFO en Linux — sin proxy de agente Windows, sin recursos compartidos SMB, sin complejidad adicional.
I/O Paralelo en Stripes — Una base de datos de 1 TB que tomaría 180 minutos con un solo stream finaliza en 42 minutos con 8 stripes. En entornos VLDB, esta es la diferencia entre cumplir o no con las ventanas de backup.
Replicación Nativa vía Bacula — Los volúmenes de Bacula ya son duraderos, cifrados, replicados offsite y gestionados con retención. El motor de replicación de PodHeitor los utiliza como transporte WAL entre instancias SQL primaria y secundaria — sin infraestructura de replicación separada.
Recuperación Instantánea — En lugar de esperar horas para la restauración completa de una base de datos de 2 TB, el mode=instant hace que la base de datos sea consultable en minutos al montar el stream de backup con WITH MOVE. La restauración completa continúa en segundo plano.
Migración Drop-In — El espacio de nombres byte-idéntico (@mssql/<INSTANCE>/<db>/data.bak) permite que los backups existentes de Enterprise sean restaurados por PodHeitor y viceversa. Cambie una línea en bacula-fd.conf, ejecute un Full, listo.
2.3 Cuándo Elegir PodHeitor
- Utiliza PodHeitor Backup y necesita una solución robusta de backup para SQL Server
- Paga por Bacula Enterprise y quiere reducir costos sin perder funcionalidades
- Ejecuta SQL Server en Linux y necesita un agente de backup nativo
- Tiene bases de datos VLDB (>500 GB) y necesita ventanas de backup más rápidas
- Necesita DR sin la complejidad de licenciamiento del AG Enterprise Edition
- Utiliza Always On AG y desea preferencia de backup + seeding automático de réplica secundaria
3. Descripción General de la Arquitectura
3.1 Diseño de Dos Niveles
El plugin utiliza una arquitectura de dos componentes principales:
- podheitor-mssql-fd.{dll,so} — cargado por el Bacula FD; gestiona la interfaz con Bacula, inicializa el backend y enruta todo el I/O via protocolo PTCOMM.
- podheitor-mssql-backend — binario Rust independiente con toda la lógica de backup, replicación y restauración SQL Server. Motores: VDI nativo, TDS via FIFO, TDS via URL, Snapshot. Subcomandos:
backup,restore,replicate,check.
3.2 Protocolo PTCOMM
PTCOMM es un protocolo binario ligero de encuadre — la capa de comunicación entre el cargador Rust plugin nativo dentro del FD y el subproceso Rust backend independiente:
| Frame | Byte | Propósito |
|---|---|---|
| Data | D |
Bloque de datos de backup (con ID de stream para N stripes) |
| Command | C |
Solicitud de operación |
| File | F |
Límite de inicio/fin de archivo |
| Info | I |
Mensaje de progreso para el log del job Bacula |
| Error | E |
Fatal — abortar job |
| Warning | W |
Advertencia no fatal |
| Terminate | T |
Finalización normal de la sesión |
Los IDs de stream permiten que N stripes paralelos sean multiplexados sobre un único par stdin/stdout. El Bacula FD ve N archivos separados.
3.3 Selección 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 del directorio de trabajo (/opt/bacula/working/mssql-state/):
- Caché de la cadena LSN — último LSN aplicado por base de datos (integridad diferencial/log)
- Estado del follower — último LSN aplicado en la replicación por base de datos
- Manifiesto de backup — disposición de la base de datos, compresión, conteo de stripes para restauración
- Tokens de recuperación — reanudación del job tras interrupción
Huella total: < 10 MB por instancia SQL. Cero staging — ningún archivo .bak se escribe en disco.
4. Análisis en Profundidad de los Motores de Backup
4.1 Motor VDI (Windows)
Tecnología: Microsoft Virtual Device Interface — API COM IClientVirtualDevice (sqlvdi.dll), implementada mediante vtables COM escritas a mano con windows-sys en Rust.
Modelo de threading (por base de datos, 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
Límite de memoria: stripes × parallel_dbs × 8 × maxtransfersize
- Predeterminado (1 stripe, 1 BD, 64 KB): 512 KB
- VLDB (8 stripes, 4 BDs, 4 MB): 1 GB — ajuste
maxtransfersizesegún corresponda
Secuencia de backup:
- Conexión ODBC + catálogo de base de datos (filtros de inclusión/exclusión/modelo de recuperación)
CreateEx(N devices)para el conteo 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) tras la finalización - Emitir sidecar
__ph_manifest.json(cadena LSN, estadísticas de compresión)
4.2 Motor TDS/FIFO (Linux)
Tecnología: tiberius (cliente TDS 7.x asíncrono en Rust puro) + named pipes POSIX.
Flujo:
El backend utiliza procesamiento asíncrono para máximo throughput — múltiples bases de datos SQL Server se respaldan en paralelo sin bloqueo de I/O.
Ciclo de vida del FIFO: Creado con modo 0600 en directorio por job. Limpiado al salir y en SIGTERM. Respaldado por tmpfs cuando está disponible.
4.3 Motor TDS URL (Azure MI / SQL Server 2022)
Servidor HTTPS Hyper 1.x integrado → CREATE CREDENTIAL + BACKUP TO URL='https://127.0.0.1:<port>/...' → SQL PUT-streams → demux → PTCOMM. La credencial se elimina tras el job. Funciona para Azure SQL MI (sin filesystem) e integración S3 de SQL 2022.
4.4 Motores de Snapshot
VSS (Windows): IVssBackupComponents → quiesce del writer SQL → DoSnapshotSet → montar en solo lectura → transmitir MDF/NDF/LDF → DeleteSnapshot.
LVM (Linux): Quiesce SQL → lvcreate --snapshot → montar en solo lectura → transmitir archivos → lvremove.
ZFS: Quiesce SQL → zfs snapshot → acceder a .zfs/snapshot/ → transmitir archivos → zfs destroy.
NetApp ONTAP: Diferido para v1.1 — actualmente devuelve un error accionable con ETA de v1.1.
5. Capacidades de Replicación
PodHeitor implementa tres modos de replicación de SQL Server utilizando volúmenes Bacula como transporte WAL. No se requiere infraestructura de replicación separada.
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 (secundario siempre en STANDBY/NORECOVERY).
5.2 AG Bootstrap
Aprovisiona una nueva réplica del AG desde la cadena Bacula sin afectar al primario: Full → Diff → Logs (WITH NORECOVERY) → ALTER DATABASE SET HADR AVAILABILITY GROUP.
5.3 Fanout (1→N Regiones)
Cadena de backup primario única consumida por N instancias de FD secundarias (São Paulo → US East → EU West). Cero carga adicional de SQL en el primario. Convergencia dentro de 2× el intervalo de log.
5.4 Máquina de Estados del Follower
El estado persistente garantiza idempotencia (reaplicar un log ya aplicado no tiene efecto), detección de brechas (activa alerta + fallback a reseed Full) y recuperación ante fallos (reanuda desde el último LSN aplicado).
6. Seguridad & Cumplimiento
6.1 Gestión de Credenciales
# Recomendado: passfile (permisos de archivo aplicados)
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 del Certificado TDE
tde_capture=yes:
- Exportar certificado DEK + PVK cifrada vía T-SQL → cifrar con clave derivada del job → transportar vía PTCOMM RestoreObject (nunca toca el filesystem)
tde_restore_cert=AUTO en la restauración:
- Obtener del RestoreObject →
CREATE MASTER KEY(si no existe) →CREATE CERTIFICATE FROM BINARY→RESTORE DATABASE WITH MOVE
Restauración TDE cross-server totalmente automatizada. Sin exportación/importación manual de certificado.
6.3 Seguridad del Transporte
| Conexión | Cifrado |
|---|---|
| TDS (no-localhost) | TLS 1.2+ requerido de forma predeterminada |
| Azure MI | TLS siempre aplicado |
| PTCOMM (backend↔adaptador) | Pipe de proceso del SO (mismo host, aislado por el SO) |
| Endpoint de métricas | HTTP solo en loopback |
6.4 Permisos Mínimos 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 Antirransomware
ransomware_hook=yes → consulta pre-backup al daemon PodHeitor ARD → anomalía reportada → job abortado con frame de error. Evita realizar backup de datos ya comprometidos por ransomware.
6.6 Integridad del Release
sha256sum -c releases/SHA256SUMS --ignore-missing
rpm --checksig podheitor-mssql-plugin-1.0.0-1.el9.x86_64.rpm
7. Observabilidad
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
Verificación de salud: GET /healthz → 200 OK {"status":"ok","version":"1.0.0"}
7.2 Trazas OpenTelemetry
Habilitar: otel_endpoint=http://otel-collector:4318
Cada job produce spans anidados: backup_job → catalog_query → backup_db por base de datos → vdi_stripe por stripe → verifyonly. Compatible con Jaeger, Zipkin, Tempo, AWS X-Ray, Azure Monitor.
8. Guía de Instalación
8.1 Requisitos Previos de 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 Instalación RPM en 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 Instalación via zip en 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 del 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. Referencia de Configuración
9.1 Archivo de Configuración
# /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 Ejemplos de FileSet
Todas las bases de datos, VDI, verificación de integridad:
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, bases de datos específicas:
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 desde réplica secundaria legible:
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 Opciones Completas de Backup
| # | Opción | Predeterminado | Descripción |
|---|---|---|---|
| 1 | database |
* |
Glob de BD (todas excepto tempdb) |
| 2 | include |
— | Inclusión explícita (múltiple) |
| 3 | exclude |
tempdb |
Glob de exclusión (múltiple) |
| 4 | user |
— | Login SQL |
| 5 | domain |
— | Dominio AD |
| 6 | password |
— | Contraseña inline (auto-redacted) |
| 7 | passfile |
— | Ruta del archivo de contraseña |
| 8 | authtype |
windows |
windows / server / azure_ad / managed_identity |
| 9 | instance |
MSSQLSERVER |
Nombre de instancia (múltiple) |
| 10 | all_instances |
off | Autodescubrir todas las instancias |
| 11 | hostname |
(local) |
Cadena de servidor ODBC |
| 12 | abort_on_error |
off | Fallar el job ante cualquier error de BD |
| 13 | copyonly |
off | COPY_ONLY: yes=todos, incremental=solo logs |
| 14 | fullbackup |
off | Forzar Full independientemente del nivel Bacula |
| 15 | skipreadonly |
off | Omitir BDs de solo lectura en Incremental |
| 16 | dblayout |
off | Almacenar disposición de BD como RestoreObject |
| 17 | lock_timeout |
0 ms |
SET LOCK_TIMEOUT |
| 18 | buffercount |
10 |
Conteo de buffers de I/O VDI |
| 19 | blocksize |
65536 |
Tamaño del bloque físico (bytes) |
| 20 | maxtransfersize |
65536 |
Transferencia VDI máxima (bytes) |
| 21 | connection_string |
— | Sobrescribir cadena de conexión ODBC |
| 22 | checksum |
yes |
WITH CHECKSUM |
| 23 | driver |
ODBC 18 | Nombre del 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 |
Limitación de ancho de banda (0=sin límite) |
| 32 | resource_governor_classifier |
— | Clasificador SQL Resource Governor |
| 33 | page_verify |
none |
none,page_audit,torn_page |
| 34 | verify_backup |
no |
RESTORE VERIFYONLY después del backup |
| 35 | dbcc_checkdb |
no |
no,physical_only,full |
| 36 | ag_preference |
auto |
auto,primary,secondary,readable_secondary |
| 37 | ag_failover_retry |
3 |
Reintentos en failover del AG durante el job |
| 38 | tde_capture |
no |
Capturar certificados TDE como RestoreObject |
| 39 | always_encrypted_cmk_report |
no |
Snapshot de metadatos CMK |
| 40 | include_system_dbs |
master,msdb,model |
Control granular de BDs de sistema |
| 41 | include_server_objects |
no |
Exportar logins, linked servers, jobs |
| 42 | include_filestream |
yes |
Consistencia FILESTREAM/FileTable |
| 43 | include_hekaton_xtp |
yes |
Archivos de checkpoint In-Memory OLTP |
| 44 | include_service_broker |
no |
Exportación de cola del 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 o identidad MI |
| 50 | snapshot_provider |
plataforma | vss,lvm,zfs |
| 51 | dry_run |
no |
Validación preflight, sin escritura |
| 52 | ransomware_hook |
no |
Abortar ante anomalía ARD |
| 53 | metrics_endpoint |
— | Prometheus /metrics host:port |
| 54 | otel_endpoint |
— | URI de trazas OTLP |
| 55 | use_sudo |
no |
Elevar permisos para gestión de FIFO en Linux |
| 56 | cluster_id |
— | Prefijo de espacio de nombres multi-cluster |
| 57 | config_file |
predeterminado de plataforma | Ruta del archivo de configuración externo |
| 58 | virtual_full |
no |
Full sintético a partir de la cadena |
9.4 Opciones Completas de Restauración
| # | Opción | Predeterminado | Descripción |
|---|---|---|---|
| 1 | instance |
MSSQLSERVER |
Instancia SQL de destino |
| 2 | database |
nombre de origen | Nombre de la nueva base de datos |
| 3 | username |
— | Login SQL |
| 4 | password |
— | Contraseña |
| 5 | domain |
— | Dominio AD |
| 6 | hostname |
(local) |
Servidor de destino |
| 7 | authtype |
windows |
Modo de autenticación |
| 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 |
— | Sobrescribir ODBC |
| 15 | checksum |
no |
WITH CHECKSUM en la restauración |
| 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 del backup | Debe coincidir con los stripes del backup |
| 19 | dbcc_checkdb |
physical_only |
DBCC después de la restauración |
| 20 | row_count_compare |
no |
Comparar conteos de filas con el manifiesto |
| 21 | single_item_target |
— | schema.table[,...] |
| 22 | sandbox_docker_image |
mssql/server:2022 | Imagen Docker de sandbox |
| 23 | ag_target_group |
— | Nombre del AG para ag_reseed |
| 24 | file_relocation_map |
— | Mapa JSON {logical: physical} |
| 25 | tde_restore_cert |
— | Paquete de certificado TDE (AUTO=desde RestoreObject) |
| 26 | drop_existing |
no |
no,yes,only_if_match |
| 27 | tail_log_before |
no |
tail-log automático antes de restauración destructiva |
| 28 | point_in_time_tz |
UTC |
Zona horaria para stop_at |
| 29 | parallel_restore_dbs |
núcleos de CPU | Restauraciones de BD simultáneas |
| 30 | progress_report_interval |
30 s |
Cadencia de progreso en el log del job |
| 31 | regexwhere |
— | Regex de reubicación de archivo Bacula |
10. Procedimientos de Restauración & Casos de Uso
10.1 Restauración Estándar en el Mismo Lugar
# bconsole restore
Plugin Options: instance=MSSQLSERVER database=AdventureWorks recovery=yes
10.2 Restauración 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 Renombrar + Reubicación de Archivos
// 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 Recuperación Instantánea
Plugin Options: mode=instant database=AdventureWorks_instant
# → BD consultable en ~35 seg (ejemplo de 100 GB)
# → Restauración completa continúa en segundo plano
10.5 Restauración de Elemento Único (Tabla)
Plugin Options: mode=single_item single_item_target=dbo.Orders,dbo.OrderItems database=recovery_sandbox
# → Contenedor Docker SQL efímero
# → Restauración completa al contenedor
# → Extracción de tabla via bcp → scripts INSERT / CSV
# → Contenedor eliminado tras la extracción
10.6 AG Reseed (Secundario Perdido)
Plugin Options: mode=ag_reseed ag_target_group=AG_Production database=prod_orders tail_log_before=yes recovery=no
# → Backup tail-log → Retirar del AG → Restaurar Full+Diff+Logs → Reintegrar al AG
10.7 Restauración TDE Cross-Server
Plugin Options: tde_restore_cert=AUTO database=SecureDB
# → Certificado obtenido del RestoreObject → instalado → RESTORE DATABASE WITH MOVE
11. Informes de Rendimiento
11.1 Throughput por Tamaño de BD y Conteo de Stripes
Entorno: SQL Server 2022 / Win Server 2025 / 16 núcleos / NVMe / 10 Gbps hacia Bacula
| Tamaño de 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 Tasas de Compresión
| Tipo de BD | none | native | native+zstd |
|---|---|---|---|
| OLTP (AdventureWorks) | 1× | 3,1× | 3,8× |
| Data Warehouse | 1× | 4,2× | 5,0× |
| Intensivo en JSON | 1× | 1,8× | 2,7× |
11.3 Rendimiento de Restauración
| Tamaño de BD | Estándar | Instantánea (consultable en) |
|---|---|---|
| 10 GB | 45 s | 8 s |
| 100 GB | 11 min | 35 s |
| 1 TB | 75 min | 3 min |
11.4 Validación E2E (v1.0.0 GA — Ejecución 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 Compatibilidad
Versiones de SQL Server
| Versión | Windows VDI | Linux TDS/FIFO | Azure MI | Always On |
|---|---|---|---|---|
| 2012, 2014 | ✅ | — | — | ✅ Básico |
| 2016, 2017 | ✅ | ✅ | — | ✅ |
| 2019, 2022 | ✅ | ✅ | ✅ | ✅ |
| Azure SQL MI | — | — | ✅ | ✅ Auto |
Versiones de PodHeitor Backup
| Versión | Estado |
|---|---|
| 14.0.x | Compatible |
| 15.0.x | ✅ Probado y certificado |
13. Guía de Dimensionamiento
Host del File Daemon
| Carga de Trabajo | RAM | CPU | Red |
|---|---|---|---|
| Pequeño (< 100 GB) | 1 GB | 2 núcleos | 1 Gbps |
| Mediano (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 memoria: parallel_dbs × stripes × buffercount × maxtransfersize
Predeterminado: 1 × 1 × 10 × 64 KB = 640 KB VLDB: 4 × 8 × 32 × 4 MB = 4 GB
Impacto en SQL Server
| Configuración | CPU | I/O | Recomendación |
|---|---|---|---|
compress=native+zstd |
+8–20% | −72% | Predeterminado — ampliamente recomendado |
stripes=4 |
SQL paralelo | +4× IOPS | Estándar para VLDB |
dbcc_checkdb=physical_only |
+10–30% | +30% | Programación semanal |
resource_governor_classifier |
Limitado por política | Limitado por política | Hosts OLTP |
14. Integración con Bacularis
Esquemas de RestoreObject
mssql-dblayout.json (emitido con 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 con tde_capture=yes):
{
"schema_version": "1.0",
"database": "SecureDB",
"certificate_name": "SecureDB_Cert",
"certificate_der_b64": "<base64>",
"encrypted_pvk_b64": "<base64>"
}
Acceso via bconsole
list restoreobjects jobid=5123
llist restoreobject jobid=5123 objectname=mssql-dblayout.json
15. Migración desde Bacula Enterprise
15.1 Compromiso de Compatibilidad
Espacio de nombres byte-idéntico. Los backups de Enterprise son 100% restaurables por PodHeitor y viceversa.
15.2 Procedimiento Sin Tiempo de Inactividad
Día 1: Instalar PodHeitor junto a Enterprise (ambos presentes en el FD)
Día 1: dry_run=yes → validar conectividad + permisos
Día 2: Primer backup Full con PodHeitor → verificar en el log de Bacula
Día 3: Cambiar FileSet: "mssql:" → "podheitor-mssql:"
Día 30+: Eliminar plugin Enterprise después del ciclo de retención (opcional)
15.3 Diferencias Notables
| Aspecto | Enterprise | PodHeitor |
|---|---|---|
checksum predeterminado |
No |
Sí (más seguro) |
| Compresión predeterminada | Ninguna | native+zstd (backups más pequeños) |
| Nombre de archivo Differential | data.bak |
data.diff.bak (distinguible, ambos reconocidos) |
Sidecars __ph_* |
No producidos | Producidos (Enterprise los ignora en la restauración) |
16. Solución de Problemas
16.1 Modos de Diagnóstico
# Preflight (sin escritura)
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 Tabla de Errores Comunes
| Error | Causa | Solución |
|---|---|---|
VD_E_ABORT |
VDI cerrada por SQL | Verificar log de errores SQL; aumentar maxtransfersize |
PTCOMM header bad length |
Salida stdout inesperada | Verificar variables de entorno de depuración ODBC |
Cannot find master key |
Captura TDE sin master key | CREATE MASTER KEY ENCRYPTION BY PASSWORD |
AG replica not preferred |
ag_preference no satisfecha | Establecer ag_preference=primary temporalmente |
Address already in use |
Conflicto de puerto de métricas | Cambiar el puerto de metrics_endpoint |
FIFO permission denied |
No pertenece al grupo mssql | usermod -aG mssql bacula o use_sudo=yes |
RESTORE VERIFYONLY failed |
Corrupción de backup o medios | Investigar con DBCC |
16.3 Ubicaciones de Logs
| Log | Linux | Windows |
|---|---|---|
| Bacula FD | /opt/bacula/log/bacula-fd.log |
Registro de Eventos de Windows |
| Backend PodHeitor | /opt/bacula/log/podheitor-mssql-<jobid>.log |
%PROGRAMDATA%Baculalog |
| SQL Server | /var/opt/mssql/log/errorlog |
Registro de Eventos de Windows |
17. Roadmap
| Versión | ETA | Aspectos Destacados |
|---|---|---|
| v1.0.0 GA | 2026-04-28 | Todos los F0–F10. 16/16 E2E PASS. |
| v1.1 | Q3 2026 | Linux ARM64, paquete DEB, instalador NSIS, NetApp ONTAP |
| v1.2 | Q4 2026 | Sidecar Kubernetes (Helm chart) |
| v1.3 | Q1 2027 | Backup de Query Store, Extended Events |
| v1.4 | Q2 2027 | Descriptor completo de plugin en la UI de Bacularis |
| v1.5 | Q3 2027 | Replicación cross-version (2019→2022) |
18. Evidencias de Validación
Resultados de Pruebas E2E (Ejecución 9 — Paquetes 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 de Pruebas Cargo
OL9: test result: ok. 311 passed; 0 failed
Win2025: test result: ok. 381 passed; 0 failed
Artefactos del 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
Licenciamiento
PodHeitor MSSQL 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?
- 💬 WhatsApp: +1 (786) 726-1749
- ✉️ Email: heitor@opentechs.lat
- 🩺 Diagnóstico gratuito — 30 min con Heitor Faria
Disponível em:
Português (Portugués, Brasil)
English (Inglés)
Español