Atualizei o comentario - coloquei tambem algumas opcoes "insanas": da um reload para ver.
gostei bastante dessas configurações insanas. com certeza adicionam muito à discussão e podem ajudar as pessoas que acessarem a publicação. muito obrigado pela ótima contribuição.
Meus 2 cents,
Um pouco mais sobre os comandos para forcar o flush do banco (via IA - mas dei uma revisada para ver se fazia sentido):
O que é um “checkpoint” no WAL
Em modo WAL, as escritas vão para o arquivo *.wal. O checkpoint copia as páginas confirmadas desse wal de volta para o arquivo principal .sqlite. Por padrão, o SQLite auto-checkpointa quando o wal atinge ~1000 páginas (≈4 MB dependendo do page size) ou quando a última conexão fecha o DB. Normalmente o checkpoint não trunca o wal; ele só “recicla” o arquivo para começar a sobrescrever do início (é mais rápido que apagar/criar de novo). (sqlite.org)
Diferenças entre FULL, RESTART e TRUNCATE
PRAGMA wal_checkpoint(FULL);
- O que faz: espera até não haver escritor ativo e até que todos os leitores estejam na snapshot mais recente. Então move todas as frames do
walpara o banco e fazfsyncno arquivo principal. - Bloqueio: bloqueia novos escritores enquanto roda; leitores continuam (não são impedidos de iniciar).
- Tamanho do WAL: pode continuar do mesmo tamanho (arquivo não é reduzido).
(sqlite.org)
PRAGMA wal_checkpoint(RESTART);
- O que faz: faz tudo que o FULL faz e depois espera até que todos os leitores passem a ler somente do arquivo principal (ninguém usando o
wal). - Efeito extra: garante que o próximo escritor vá reiniciar o
waldo começo (o cabeçalho é “resetado”). - Bloqueio: como no FULL, impede novos escritores enquanto está pendente; leitores não são impedidos, mas o comando espera os leitores atuais terminarem de usar o
wal.
(sqlite.org)
PRAGMA wal_checkpoint(TRUNCATE);
- O que faz: igual ao RESTART mais um passo extra: trunca o arquivo
walpara 0 bytes antes de retornar com sucesso (libera espaço em disco). - Bloqueio: idem ao RESTART.
- Tamanho do WAL: vai a zero se o checkpoint completar.
(sqlite.org)
Observação útil: o comando
PRAGMA wal_checkpointretorna uma linha com três inteiros:
busy, log, checkpointed.busy=1indica que um FULL/RESTART/TRUNCATE não conseguiu completar (ex.: alguém segurava lock). (sqlite.org)
Como isso afeta sua aplicação e as configs já aplicadas
-
Concorrência/leitura:
FULL,RESTARTeTRUNCATEbloqueiam novos escritores durante a operação (usam o writer lock) e podem invocar o busy handler; leitores seguem funcionando, mas oRESTART/TRUNCATEesperam leitores atuais saírem dowalpara conseguir “reiniciar”/truncar. Planeje executar em janelas de menor tráfego de escrita. (sqlite.org)
-
Espaço em disco:
- Somente
TRUNCATEreduz fisicamente o tamanho do arquivowal.FULLeRESTARTdeixam o arquivo como está (ele será reutilizado). Se você precisa liberar espaço imediatamente (após operações grandes ou umVACUUM),TRUNCATEé o certo. (sqlite.org)
- Somente
-
Com
WAL + synchronous=NORMAL:- É um bom equilíbrio de desempenho/segurança. Use FULL periodicamente se quiser “forçar” o flush para o
.sqlitesem mexer no tamanho dowal. Use RESTART se owalcrescer porque há leitores de longa duração; ele garante que o próximo write recomece do início. Use TRUNCATE quando o objetivo for recuperar espaço. (sqlite.org)
- É um bom equilíbrio de desempenho/segurança. Use FULL periodicamente se quiser “forçar” o flush para o
-
Auto-checkpoint vs manual:
- O auto-checkpoint (por padrão ou via
PRAGMA wal_autocheckpoint) é PASSIVE – não bloqueia e pode deixar trabalho pendente se houver leitores/escritores. Os modos FULL/RESTART/TRUNCATE são “mais agressivos” e podem bloquear para concluir. (sqlite.org)
- O auto-checkpoint (por padrão ou via
-
Tamanho máximo do WAL:
- Se a preocupação é “não deixar o arquivo crescer demais”, combine com
PRAGMA journal_size_limit(ex.:journal_size_limit=0faz truncar/journals voltarem ao mínimo após ficarem inativos). Isso não substituiTRUNCATE, mas ajuda a manter o footprint. (SQLite)
- Se a preocupação é “não deixar o arquivo crescer demais”, combine com
Recomendações práticas
-
Rotina segura para produção (balanceada):
-- manutenção periódica em horário de baixo tráfego PRAGMA wal_checkpoint(FULL);Garante que tudo no
walfoi aplicado ao.sqlite, sem “pausas” tão longas quanto RESTART/TRUNCATE. -
Quando o WAL está crescendo por leitores longos (ETLs, backups, conexões com long transactions):
PRAGMA wal_checkpoint(RESTART);Faz um “limpa” lógico: o próximo writer começa no início do WAL, limitando crescimento.
-
Para liberar espaço em disco agora (pós grandes INSERT/DELETE/VACUUM, dispositivos com storage limitado):
PRAGMA wal_checkpoint(TRUNCATE);Trunca o arquivo a 0 bytes (se conseguir os locks/leitores concluírem).
-
Dicas de operação:
- Rode o checkpoint a partir de uma conexão de manutenção com
busy_timeoutconfigurado, para que FULL/RESTART/TRUNCATE possam esperar locks de forma amigável. Todos esses modos pegam um lock exclusivo de checkpoint e (para FULL/RESTART/TRUNCATE) também o lock de escrita. (sqlite.org) - Se a meta é limitar tamanho continuamente, combine auto-checkpoint com
journal_size_limite, ocasionalmente, umRESTART/TRUNCATEem janela de manutenção. (sqlite.org, SQLite)
- Rode o checkpoint a partir de uma conexão de manutenção com
Aqui vai um fluxo de decisão prático para escolher entre os modos de checkpoint (FULL, RESTART, TRUNCATE) dependendo da situação da sua aplicação:
🔄 Fluxo de decisão para wal_checkpoint
1. Seu objetivo é apenas garantir consistência (flush do WAL → arquivo principal)?
➡️ Use PRAGMA wal_checkpoint(FULL);
- Copia tudo do WAL para o
.sqlite. - Não reduz tamanho do arquivo.
- Bloqueia apenas novos escritores enquanto roda.
✅ Melhor escolha para manutenção periódica (fim do dia, cron jobs).
2. O arquivo WAL está crescendo porque há leitores longos segurando páginas antigas?
➡️ Use PRAGMA wal_checkpoint(RESTART);
- Faz o mesmo que o
FULL. - Mas espera todos os leitores saírem do WAL.
- Garante que o próximo writer começará do início do arquivo WAL.
✅ Ideal se você percebe que o WAL não diminui de tamanho mesmo após checkpoints comuns.
3. Precisa recuperar espaço em disco imediatamente?
➡️ Use PRAGMA wal_checkpoint(TRUNCATE);
- Igual ao
RESTART, mais truncamento físico do WAL para 0 bytes. - Útil após operações grandes (muitos
INSERT/DELETEouVACUUM).
⚠️ Pode ter pausa perceptível, pois espera leitores terminarem.
✅ Ideal em ambientes com limite de espaço em disco.
🧭 Resumo em tabela
| Situação | Melhor checkpoint |
|---|---|
| Flush periódico de segurança | FULL |
| WAL crescendo por leitores longos | RESTART |
| Preciso liberar espaço no disco | TRUNCATE |
⚡ Boas práticas extras
- Configure
PRAGMA wal_autocheckpoint(ex.: 1000 páginas ≈ 4 MB) para checkpoints automáticos leves (modo PASSIVE). - Use
PRAGMA journal_size_limitpara manter o WAL dentro de um teto (ex.:PRAGMA journal_size_limit=50MB;). - Agende
FULL/RESTART/TRUNCATEem janelas de baixa atividade para evitar pausas perceptíveis.