Completo, diferencial o incremental: cómo elegir tu estrategia de respaldo (y probarla bloque a bloque con SQLite)
Autor: Sebastian Alejandro Cortez Apaza, estudiante de Ingeniería de Sistemas de la Universidad Privada de Tacna, curso Base de Datos II. 🔗 Demo en vivo: https://sebacor-13.github.io/backup-strategies-sqlite/ 💻 Reposi
Autor: Sebastian Alejandro Cortez Apaza, estudiante de Ingeniería de Sistemas de la Universidad Privada de Tacna, curso Base de Datos II.
🔗 Demo en vivo: https://sebacor-13.github.io/backup-strategies-sqlite/
💻 Repositorio público: https://github.com/SEBACOR-13/backup-strategies-sqlite
1. Los atacantes también buscan tus respaldos
Según el estudio de Sophos de 2024, aplicado a casi 3 000 organizaciones, en el 94 % de los ataques de ransomware los delincuentes intentaron comprometer también los respaldos, y lo lograron en el 57 % de esos casos. Cuando lo consiguieron, las víctimas tuvieron casi el doble de probabilidad de pagar el rescate, y el costo de recuperación fue unas ocho veces mayor (Adam, 2024).
Por eso la pregunta ya no es solo “¿tengo respaldo?”, sino también:
- ¿qué tipo de respaldo tengo?
- ¿cuántas piezas necesito para restaurarlo?
- ¿está cifrado y separado del sistema atacado?
- ¿lo he probado alguna vez?
En este artículo comparo las tres políticas clásicas (completa, diferencial e incremental) con datos medidos, gracias a BlockBackupLab, una aplicación que respalda un archivo SQLite real página por página.
2. Las tres políticas, en una frase cada una
La literatura clásica de respaldos distingue entre copiar todo y copiar solo lo modificado (Chervenak et al., 1998):
| Política | Qué copia | Para restaurar necesito | Ventaja | Riesgo |
|---|---|---|---|---|
| Completa | Todo, cada vez | 1 pieza | Simplicidad y restauración rápida | Mucho espacio y ventanas largas |
| Diferencial | Lo que cambió desde el último completo | 2 piezas: completo + último diferencial | Restauración sencilla | Crece cada día hasta el siguiente completo |
| Incremental | Lo que cambió desde el respaldo anterior | Completo + todos los incrementales | Mínimo espacio y ventanas cortas | La cadena es frágil: si falta un eslabón, se pierde lo posterior |
Un esquema típico es un completo el domingo y diferenciales o incrementales de lunes a sábado.
3. ¿Qué significa “lo que cambió”? Respaldos por bloques
Las herramientas modernas no comparan filas ni archivos enteros: comparan bloques. SQLite es un caso ideal para entenderlo, porque toda la base vive en un único archivo dividido en páginas de tamaño fijo. El tamaño de página se guarda en la cabecera, en el desplazamiento 16 (SQLite, s.f.-a).
La idea es simple:
- Divido el archivo en páginas de 4 KB.
- Calculo el SHA-256 de cada página.
- Comparo esas huellas con las del respaldo de referencia y copio solo las páginas distintas.
Así funciona también sqlite3_rsync, la herramienta oficial de SQLite para copiar una base viva: la réplica envía hashes de sus páginas y el origen devuelve solo las que difieren. En bases parecidas, el tráfico puede ser del orden del 0,01 % del tamaño (SQLite, s.f.-c). PostgreSQL 17 aplica la misma idea en su respaldo incremental nativo.
// Tamaño de página: bytes 16-17 de la cabecera, big-endian (1 significa 65 536)
export function tamanoPagina(bytes) {
const v = (bytes[16] << 8) | bytes[17]
return v === 1 ? 65536 : v
}
export async function crearRespaldo(bytes, tipo, catalogo) {
const hashes = await hashesDePaginas(bytes) // SHA-256 de cada página
const base = tipo === 'diferencial'
? [...catalogo].reverse().find((b) => b.tipo === 'completo') // último completo
: tipo === 'incremental' ? catalogo.at(-1) : null // respaldo anterior
const cambiadas = hashes.flatMap((h, i) => (!base || base.hashes[i] !== h ? [i] : []))
return { tipo, padre: base?.id ?? null, hashes, paginas: cambiadas.map((i) => copiaPagina(bytes, i)) }
}
Para restaurar, se aplica la cadena en orden: primero el completo y luego cada respaldo posterior, sobrescribiendo sus páginas. Al final se verifica el SHA-256 del archivo reconstruido contra el original.
Ojo en SQLite real: nunca copies el archivo
.dbconcpmientras está en uso. Usa la Online Backup API,VACUUM INTO 'respaldo.db'osqlite3_rsync, que garantizan una copia consistente (SQLite, s.f.-b). Para respaldos continuos existe Litestream, que replica el WAL de SQLite hacia almacenamiento S3.
4. BlockBackupLab: medir en lugar de suponer
La aplicación simula un inventario con 4 almacenes, 300 productos y 6 000 movimientos sobre SQLite real, ejecutado en el navegador con sql.js (WebAssembly). Cada vez que avanzas un día simulado:
- Se registran unos 120 movimientos nuevos y se actualiza el stock.
- Se ejecuta el respaldo que indique la política.
- El respaldo se comprime con gzip y se cifra con AES-256-GCM.
4.1 Resultados de dos semanas simuladas
Con los mismos datos, al final la base pesa 584 KB (146 páginas). Estos son los resultados medidos, sin comprimir:
| Política | Almacenamiento total | Páginas copiadas por día (lun → sáb, semana 1) | Piezas para restaurar el día 13 |
|---|---|---|---|
| Completo diario | 7,27 MB | 122 → 132 (todo) | 1 |
| Completo dominical + diferencial | 2,45 MB | 25 → 35 (crece) | 2 |
| Completo dominical + incremental | 2,23 MB | 25 → 26 (estable) | 7 |
Lectura de los resultados:
- El completo diario ocupa unas 3 veces más que las otras dos políticas.
- El diferencial crece cada día: el sábado vuelve a copiar todo lo del lunes. Aun así, restaurar solo necesita dos piezas.
- El incremental copia siempre lo mínimo, pero restaurar un sábado exige leer y aplicar siete archivos, sin que falte ninguno.
En la app hay un botón 🗑 que simula “perder” un respaldo, por un disco dañado o un borrado accidental. Si se pierde un incremental intermedio, la cadena de restauración de los días siguientes se rompe y la aplicación lo indica en rojo.
5. Cifrar y verificar: el respaldo como objetivo
Si el atacante puede leer o borrar tus respaldos, no tienes respaldos. BlockBackupLab empaqueta cada uno así:
- Serializa las páginas con una cabecera JSON de metadatos.
- Comprime con gzip: un completo de 480 KB queda en unos 186 KB.
- Cifra con AES-256-GCM, un modo autenticado: cualquier byte alterado hace fallar el descifrado (Dworkin, 2007).
- Deriva la clave desde una frase con PBKDF2-HMAC-SHA256 y 600 000 iteraciones, el valor que recomienda OWASP (OWASP Foundation, s.f.).
const clave = await crypto.subtle.deriveKey(
{ name: 'PBKDF2', salt, iterations: 600000, hash: 'SHA-256' },
material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt'])
const cifrado = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, clave, comprimido)
En la demostración, un ransomware simulado cifra el archivo de la base y lo vuelve ilegible. La restauración trabaja solo con los paquetes cifrados y hace lo siguiente:
- Los descifra y reconstruye el archivo página por página.
- Comprueba que el SHA-256 sea idéntico al original.
- Ejecuta
PRAGMA integrity_check, que devuelveok. - Compara el número de filas de cada tabla.
6. De 3-2-1 a 3-2-1-1-0
La regla clásica pide 3 copias, en 2 medios distintos y 1 fuera del sitio (Ruggiero & Heckathorn, 2012). Frente al ransomware, la industria la amplió a 3-2-1-1-0:
- 1 copia inmutable o desconectada (offline o air-gapped), que el atacante no pueda cifrar ni borrar.
- 0 errores al verificar las restauraciones.
Es lo mismo que pide la guía #StopRansomware de CISA, la NSA y el FBI: mantener respaldos desconectados y cifrados, y probar con regularidad su disponibilidad e integridad (CISA et al., 2023).
A esto se suma una política de retención. La aplicación aplica el esquema GFS (abuelo-padre-hijo): conserva 7 respaldos diarios, 4 semanales y 6 mensuales, y marca el resto como “expira”.
7. Despliegue automatizado
El repositorio público se despliega solo, sin pasos manuales:
-
deploy.yml: en cada push amainejecuta 11 pruebas con Vitest. Cubren cadenas completas, diferenciales e incrementales, la ruptura de la cadena, el ransomware, el cifrado con frase incorrecta o paquete alterado, la comparación de políticas y la retención GFS. Después construye con Vite, publica en GitHub Pages y hace una prueba de humo. -
simulacro.yml: cada lunes repite el simulacro de restauración, porque un respaldo que nunca se restaura no está probado.
8. ¿Cuál elijo?
- Base pequeña o RTO muy exigente → completo frecuente, porque se restaura en un solo paso.
- Equilibrio entre espacio y simplicidad → completo semanal + diferencial diario.
- Base grande con pocos cambios diarios, o ancho de banda limitado → completo semanal + incremental, con verificación automática de la cadena y copias redundantes de cada eslabón.
- RPO de minutos → ninguna de las tres basta por sí sola. Hay que sumar replicación o archivado continuo del log de transacciones (WAL en SQLite o PostgreSQL, binlog en MySQL).
Y siempre: cifra, separa al menos una copia del sistema principal y ensaya la restauración.
Referencias
Adam, S. (2024). The impact of compromised backups on ransomware outcomes. Sophos. https://www.sophos.com/en-us/blog/the-impact-of-compromised-backups-on-ransomware-outcomes
Chervenak, A., Vellanki, V., & Kurmas, Z. (1998). Protecting file systems: A survey of backup techniques. En Proceedings of the Joint NASA and IEEE Mass Storage Conference. https://www.researchgate.net/publication/2431989_Protecting_File_Systems_A_Survey_of_Backup_Techniques
CISA, MS-ISAC, NSA & FBI. (2023). #StopRansomware guide. Cybersecurity and Infrastructure Security Agency. https://www.cisa.gov/stopransomware/ransomware-guide
Dworkin, M. (2007). Recommendation for block cipher modes of operation: Galois/Counter Mode (GCM) and GMAC (NIST Special Publication 800-38D). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-38D
OWASP Foundation. (s.f.). Password storage cheat sheet. OWASP Cheat Sheet Series. Recuperado el 3 de octubre de 2026, de https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
Ruggiero, P., & Heckathorn, M. A. (2012). Data backup options. United States Computer Emergency Readiness Team (US-CERT). https://www.cisa.gov/sites/default/files/publications/data_backup_options.pdf
SQLite. (s.f.-a). Database file format. Recuperado el 3 de octubre de 2026, de https://www.sqlite.org/fileformat.html
SQLite. (s.f.-b). SQLite backup API. Recuperado el 3 de octubre de 2026, de https://www.sqlite.org/backup.html
SQLite. (s.f.-c). Database remote-copy tool for SQLite (sqlite3_rsync). Recuperado el 3 de octubre de 2026, de https://www.sqlite.org/rsync.html
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.


