Pular para o conteúdo

Bug do WAL-reset do SQLite: pelo menos 16 anos escondido, 19 casos de corrupção na Tailscale

A Tailscale contou como achou o bug WAL-reset do SQLite, texto assinado por Alex Chan. É uma condição de corrida rara que, segundo a estimativa deles, existia no código do SQLite havia pelo menos 16 anos.

O que acontece

Quando uma escrita ocorre em um momento específico durante um checkpoint do WAL, o processo de checkpoint se confunde: acredita que páginas foram copiadas do WAL para o banco, mas elas nunca foram. Esses dados se perdem de forma permanente e o banco fica corrompido. A Tailscale era especialmente exposta porque assume o controle manual do checkpoint e o executa de forma agressiva.

Como chegaram lá

O sinal inicial foi corrupção recorrente em backups: 19 instâncias em 6 meses. A equipe contratou o suporte profissional do SQLite, e os desenvolvedores do SQLite criaram uma ferramenta de depuração chamada tmstmpvfs. Logs adicionais confirmaram a condição de corrida. Depois, a Tailscale implementou alertas para detectar tentativas ativas de corrupção.

Impacto e correção

Os efeitos incluíram indisponibilidade do plano de controle em shards afetados, dispositivos novos sem conseguir conectar durante a recuperação, perda temporária de acesso ao console de administração e à API, e alguns dados de configuração que não persistiam. Segundo o texto, as versões anteriores à 3.51.3 são afetadas. A correção adiciona uma verificação extra na função de checkpoint, para detectar quando o WAL foi resetado por outra thread.

O que serve de lição

O caso mostra o custo de um padrão incomum de uso: o bug era raro, e só um usuário que controla o checkpoint manualmente e o executa com frequência o encontrava com regularidade. O texto também registra o desgaste causado por vários incidentes seguidos na página de status.