Litestream: replicação de SQLite em tempo real para backups confiáveis
1. O Problema dos Backups em SQLite em Produção
1.1. Limitações tradicionais
O SQLite é amplamente utilizado em produção, mas seus mecanismos tradicionais de backup apresentam sérias limitações. O comando .backup do sqlite3 requer bloqueio exclusivo de escrita durante toda a operação, o que pode paralisar aplicações por segundos ou minutos em bancos de dados grandes. Pior: se o processo falhar durante o backup, o arquivo resultante pode ficar corrompido e inutilizável.
# Backup tradicional com sqlite3 (bloqueia escrita)
sqlite3 /var/data/app.db ".backup /backups/app_$(date +%Y%m%d).db"
1.2. Cenários onde SQLite é usado em produção
SQLite brilha em ambientes com recursos limitados: dispositivos embarcados, servidores edge, aplicações single-server, prototipagem rápida e sites estáticos que precisam de persistência. Nesses cenários, um banco PostgreSQL ou MySQL seria superdimensionado e complexo demais para gerenciar.
1.3. A necessidade de replicação contínua e PITR
Backups diários não são suficientes para aplicações que processam dados continuamente. A perda de algumas horas de dados pode ser catastrófica. A recuperação point-in-time (PITR) permite restaurar o banco para qualquer momento específico, não apenas para o último backup completo.
2. O que é o Litestream e Como Funciona
2.1. Conceito de replicação baseada em WAL
O Litestream aproveita o Write-Ahead Log (WAL) do SQLite. Quando o SQLite opera em modo WAL (padrão desde a versão 3.7.0), todas as modificações são escritas primeiro em um arquivo de log separado antes de serem aplicadas ao banco principal. O Litestream monitora continuamente esse arquivo WAL, capturando cada alteração em tempo real.
2.2. Fluxo de replicação
O processo é simples e eficiente:
- O SQLite escreve alterações no arquivo WAL
- O Litestream detecta as novas páginas modificadas
- As páginas são compactadas e enviadas incrementalmente para o destino configurado
- Periodicamente, um snapshot completo do banco é gerado
# Fluxo básico de replicação
SQLite app.db → app.db-wal (WAL) → Litestream → S3/MinIO/GCS
2.3. Diferenças para soluções concorrentes
Diferente do rqlite (que cria um cluster Raft sobre SQLite) ou do Dqlite (que substitui o SQLite vanilla), o Litestream não altera o comportamento do SQLite. Ele opera como um processo separado, sem modificar o banco de dados original. É uma solução de backup, não de alta disponibilidade.
3. Arquitetura e Modos de Operação
3.1. Modo replicação contínua vs. snapshot periódico
O Litestream opera em dois modos complementares:
- Replicação contínua: envia páginas WAL modificadas para o destino em tempo real (intervalo de ~1 segundo)
- Snapshot periódico: gera uma cópia completa do banco em intervalos configuráveis (recomendado a cada 24h ou 100MB de WAL)
# Configuração típica: snapshot a cada 6 horas
snapshot-interval: 6h
3.2. Destinos suportados
O Litestream suporta múltiplos backends de armazenamento:
- Amazon S3 (e compatíveis como MinIO)
- Backblaze B2
- Google Cloud Storage
- Azure Blob Storage
- Sistema de arquivos local (para testes)
3.3. Estratégia de retenção
A retenção inteligente mantém snapshots e logs WAL por períodos configuráveis, permitindo PITR dentro da janela de retenção:
# Manter snapshots por 30 dias, logs WAL por 7 dias
retention:
snapshots: 30d
wal: 7d
4. Instalação e Configuração Essencial
4.1. Instalação
# Linux (amd64)
curl -L https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.tar.gz | tar xz
sudo mv litestream /usr/local/bin/
# macOS
brew install litestream
4.2. Estrutura do arquivo de configuração
O Litestream usa um arquivo YAML para configuração. Exemplo completo:
# /etc/litestream.yml
dbs:
- path: /var/data/app.db
replicas:
- url: s3://my-bucket/backups/app
access-key-id: AKIAIOSFODNN7EXAMPLE
secret-access-key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region: us-east-1
snapshot-interval: 24h
validation-interval: 1h
4.3. Exemplo prático: SQLite local → bucket S3
# 1. Criar bucket S3 (via AWS CLI)
aws s3 mb s3://meus-backups-sqlite
# 2. Configurar Litestream
cat > /etc/litestream.yml << 'EOF'
dbs:
- path: /var/lib/app/database.sqlite
replicas:
- url: s3://meus-backups-sqlite/app-producao
access-key-id: ${AWS_ACCESS_KEY_ID}
secret-access-key: ${AWS_SECRET_ACCESS_KEY}
region: us-east-1
EOF
# 3. Iniciar o serviço
litestream replicate -config /etc/litestream.yml
5. Restauração e Recuperação de Desastres
5.1. Restauração básica
# Restaurar para o estado mais recente
litestream restore -o /tmp/app-restaurado.db s3://meus-backups-sqlite/app-producao
5.2. Restauração point-in-time
# Restaurar para um momento específico
litestream restore -o /tmp/app-2024-01-15.db \
-timestamp "2024-01-15T14:30:00Z" \
s3://meus-backups-sqlite/app-producao
# Usando geração (posição do log WAL)
litestream restore -o /tmp/app-generacao-42.db \
-generation 42 \
s3://meus-backups-sqlite/app-producao
5.3. Recuperação para diretório diferente e verificação
# Restaurar e verificar integridade
litestream restore -o /data/novo-app.db \
s3://meus-backups-sqlite/app-producao
# Verificar integridade do banco restaurado
sqlite3 /data/novo-app.db "PRAGMA integrity_check;"
6. Integração com Aplicações e Práticas Recomendadas
6.1. Uso com frameworks
Em aplicações Rails, configure o caminho do banco no database.yml:
# config/database.yml
production:
adapter: sqlite3
database: /var/data/app_production.sqlite3
pool: 5
timeout: 5000
Para Node.js com better-sqlite3:
const Database = require('better-sqlite3');
const db = new Database('/var/data/app.db', {
wal: true,
timeout: 5000
});
6.2. Monitoramento
# Verificar status da replicação
litestream status
# Logs do Litestream (systemd)
journalctl -u litestream -f
# Métricas importantes no log:
# "replicating" - indica replicação ativa
# "snapshot created" - snapshot completo gerado
# "error" - problemas de conexão com o storage
6.3. Boas práticas
# Configuração recomendada para produção
snapshot-interval: 6h # Reduzir para 1h em bancos críticos
wal-max-size: 100MB # Evitar WAL muito grande
validation-interval: 1h # Verificar integridade periodicamente
# Rotação de backups: configurar lifecycle no S3
aws s3api put-bucket-lifecycle-configuration \
--bucket meus-backups-sqlite \
--lifecycle-configuration '{
"Rules": [{
"ID": "expire-old-snapshots",
"Filter": {"Prefix": "app-producao/snapshots"},
"Status": "Enabled",
"Expiration": {"Days": 90}
}]
}'
7. Limitações, Riscos e Casos de Uso Reais
7.1. Limitações
- Replicação assíncrona: pode haver perda de até alguns segundos de dados em caso de falha catastrófica
- Sem failover automático: o Litestream não substitui o banco original automaticamente
- Overhead de I/O: a replicação contínua adiciona carga de leitura no disco
7.2. Riscos
# Risco: concorrência com VACUUM
# O VACUUM tradicional pode causar inconsistências no WAL
# Solução: usar PRAGMA auto_vacuum = INCREMENTAL em vez de VACUUM
# Risco: perda de dados na janela de replicação
# Em média, 1-2 segundos de dados podem ser perdidos
# Mitigação: configurar checkpoint frequente no SQLite
PRAGMA wal_autocheckpoint = 1000; # Checkpoint a cada 1000 páginas
7.3. Casos de uso reais
- Edge computing: dispositivos IoT que coletam dados localmente e replicam para a nuvem
- Sites estáticos com SQLite: blogs, documentações e sites pessoais que precisam de backup confiável
- Servidores single-node: aplicações internas, dashboards, ferramentas de administração
- Ambientes de desenvolvimento: backup automático de bancos de desenvolvimento sem complexidade
Referências
- Documentação oficial do Litestream — Guia completo de instalação, configuração e referência de comandos
- GitHub do Litestream — Código fonte, issues, discussões e exemplos avançados
- SQLite WAL mode documentation — Documentação oficial sobre o modo Write-Ahead Log do SQLite
- Tutorial: Backup de SQLite com Litestream e S3 — Tutorial prático da DigitalOcean para configuração em produção
- Litestream vs rqlite vs Dqlite: comparação — Artigo comparativo de ferramentas de replicação para SQLite
- Litestream: replicação para edge computing — Caso de uso real em edge computing pela Fly.io