Executando verificação de segurança...
1

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.

Carregando publicação patrocinada...
3

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 wal para o banco e faz fsync no 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 escritorreiniciar o wal do 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 wal para 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_checkpoint retorna uma linha com três inteiros:
busy, log, checkpointed. busy=1 indica 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, RESTART e TRUNCATE bloqueiam novos escritores durante a operação (usam o writer lock) e podem invocar o busy handler; leitores seguem funcionando, mas o RESTART/TRUNCATE esperam leitores atuais saírem do wal para conseguir “reiniciar”/truncar. Planeje executar em janelas de menor tráfego de escrita. (sqlite.org)
  • Espaço em disco:

    • Somente TRUNCATE reduz fisicamente o tamanho do arquivo wal. FULL e RESTART deixam o arquivo como está (ele será reutilizado). Se você precisa liberar espaço imediatamente (após operações grandes ou um VACUUM), TRUNCATE é o certo. (sqlite.org)
  • Com WAL + synchronous=NORMAL:

    • É um bom equilíbrio de desempenho/segurança. Use FULL periodicamente se quiser “forçar” o flush para o .sqlite sem mexer no tamanho do wal. Use RESTART se o wal crescer 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)
  • 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)
  • 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=0 faz truncar/journals voltarem ao mínimo após ficarem inativos). Isso não substitui TRUNCATE, mas ajuda a manter o footprint. (SQLite)

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 wal foi 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_timeout configurado, 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_limit e, ocasionalmente, um RESTART/TRUNCATE em janela de manutenção. (sqlite.org, SQLite)

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/DELETE ou VACUUM).
    ⚠️ Pode ter pausa perceptível, pois espera leitores terminarem.
    ✅ Ideal em ambientes com limite de espaço em disco.

🧭 Resumo em tabela

SituaçãoMelhor checkpoint
Flush periódico de segurançaFULL
WAL crescendo por leitores longosRESTART
Preciso liberar espaço no discoTRUNCATE

⚡ 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_limit para manter o WAL dentro de um teto (ex.: PRAGMA journal_size_limit=50MB;).
  • Agende FULL/RESTART/TRUNCATE em janelas de baixa atividade para evitar pausas perceptíveis.
2
1