>_ DevTrendses

Idioma

Inicio

Lenguajes

Secciones

Frontend Backend Móvil DevOps AI / ML GameDev Blockchain Embebidos Seguridad
Go

Cómo hacer backup de SQLite a S3 en tiempo real sin perder datos

¿Te encanta SQLite por su simplicidad? Levanta un VPS nuevo, lanza un servicio pequeño, coloca un archivo de base de datos junto a él, y todo funciona con respuesta instantánea. Sin contenedores Docker adicionales con PostgreSQL, sin gestión de usuarios ni configuración de permisos de acceso. Hermoso.

Los problemas comienzan cuando el servidor se cae inesperadamente o el proveedor "accidentalmente" elimina tu disco. Si hacías backup una vez al día a través de cron, perdiste un día completo de usuarios y pedidos. Si intentaste copiar el archivo de base de datos con un simple cp mientras se estaban realizando escrituras, terminaste con un archivo corrupto que ni siquiera SQLite puede abrir.

El creador de la conocida base de datos clave-valor BoltDB, Ben Johnson, se enfrentó exactamente a este dilema y construyó Litestream. Es una pequeña herramienta en Go que resuelve el problema del backup de SQLite de una vez por todas.

Qué hace Litestream y por qué lo necesitas

Litestream se ejecuta como un proceso en segundo plano en el mismo servidor que tu aplicación. Su trabajo es transmitir continuamente los cambios desde tu base de datos SQLite local a almacenamiento remoto. Puede ser un cloud compatible con S3, Yandex Object Storage, MinIO, o simplemente una carpeta en otro disco montado.

Como resultado, obtienes un sistema de recuperación ante desastres listo para usar. Si tu VPS se va al traste, levantas una nueva instancia, ejecutas un único comando de restauración, y la base de datos se recupera justo hasta la última transacción antes del fallo.

La característica principal de la herramienta es la fiabilidad. Interactúa con la base de datos estrictamente a través de la API oficial de C de SQLite, no leyendo ciegamente bytes sin procesar del disco. Esto garantiza que las fases de escritura no se superpongan con la compresión o los puntos de control del journal, y que la base de datos no se convierta en un archivo corrupto.

Cómo funciona la replicación internamente

Para entender cómo funciona, recordemos el modo WAL (Write-Ahead Logging) de SQLite.

Por defecto, SQLite escribe los cambios directamente en el archivo principal .db. En modo WAL, todas las transacciones nuevas van primero a un journal separado con la extensión -wal. Periódicamente, estos cambios se vuelcan de vuelta al archivo principal. Este enfoque acelera las escrituras y no bloquea las lecturas.

Litestream utiliza este mecanismo:

  1. Cambia la base de datos a modo WAL.
  2. Monitorea la aparición de nuevas páginas en el archivo WAL.
  3. Copia estos cambios y los envía en pequeños segmentos a S3.
  4. Controla el proceso de checkpoint para que SQLite no borre el WAL prematuramente antes de que los datos se hayan subido a la nube.

El retraso en el envío de datos a S3 es de apenas unos segundos. Si el servidor se rompe, lo máximo que pierdes son datos de los últimos un par de segundos.

Configuración y ejemplo de uso

Puedes iniciar la replicación en un par de minutos. Solo descarga el binario o usa una imagen Docker lista para usar.

Primero, creemos el archivo de configuración litestream.yml:

dbs:
  - path: /var/lib/my-app/production.db
    replicas:
      - url: s3://my-backup-bucket/production.db

Los parámetros de conexión a S3 como las claves de acceso y el endpoint suelen pasarse mediante variables de entorno estándar: AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY.

El proceso se inicia con un simple comando:

litestream replicate -config /etc/litestream.yml

A menudo Litestream se ejecuta en el mismo contenedor Docker que la aplicación principal, usando un orquestador de procesos ligero como entrypoint.sh o supervisord.

Si el servidor se cayó y necesitas desplegar la base de datos en una nueva ubicación, ejecutas el comando de restauración antes de iniciar la aplicación:

litestream restore -o /var/lib/my-app/production.db s3://my-backup-bucket/production.db

La utilidad obtendrá el último volcado base del bucket, descargará todos los segmentos WAL faltantes encima, ensamblará un archivo de base de datos completo y lo colocará en la ruta especificada.

Limitaciones y consideraciones

La herramienta se ve muy atractiva, pero Litestream tiene un alcance claro y sus propias limitaciones.

Primero, la utilidad requiere que el modo WAL esté habilitado. Si tu aplicación o una biblioteca de driver de base de datos específica es incompatible con él, nada funcionará.

Segundo, esta es una herramienta de recuperación ante desastres, no para escalado horizontal de lectura. No puedes usar Litestream para levantar cinco copias del servicio en diferentes servidores leyendo simultáneamente desde la misma base de datos replicada. Para escenarios distribuidos con múltiples nodos, es mejor que busques LiteFS del mismo equipo o proyectos como rqlite.

Tercero, si tienes una base de datos enorme de cientos de gigabytes con escrituras pesadas constantes, los costos de tráfico S3 y solicitudes API pueden ser una sorpresa desagradable. La herramienta está diseñada para cargas de trabajo pequeñas a medianas.

A quién le será útil este proyecto

Litestream elimina la necesidad de configurar bases de datos pesadas donde no hay una necesidad real de ellas. Es una excelente opción para:

  • Bots de Telegram y APIs REST en Go, Python o Node.js con una única instancia de aplicación.
  • Proyectos en frameworks como PocketBase o Directus ejecutándose sobre SQLite.
  • Servicios autoalojados personales ejecutándose en VPS baratos.
  • Microservicios con caché local o aislamiento de datos de clientes.

Si has querido mover un proyecto personal a SQLite pero el miedo a perder tu disco te frenaba, prueba a añadir Litestream. La configuración lleva media hora, pero dormirás tranquilo.

Proyectos relacionados