Um banco de dados relacional embutido, escrito do zero em Rust.
Pager, B+Tree, write-ahead log com recovery ARIES, SQL e MVCC — sem engine por baixo.
Rode o banco aqui
Isto é o motor de verdade, o mesmo binário do repositório, compilado para
WebAssembly. O mesmo pager, a mesma B+Tree, o mesmo log. O que muda é o disco: no lugar dele
há um arquivo em memória dentro da sua aba, que existe enquanto a página estiver aberta e
some quando você fechar. Nada sai do seu navegador — não há servidor nenhum atrás disto.
O que ele é, e o que não é
É um motor de armazenamento completo: páginas de 4 KB gerenciadas na mão,
índice B+Tree com split e fusão, log de escrita adiantada com as três passadas do ARIES,
camada SQL com junções e índices secundários, e MVCC com snapshot isolation.
Não é para produção, e nunca vai ser. Tem um escritor por vez, o checkpoint
para o mundo, chave grande não cabe, e página de dados não tem soma de verificação contra
escrita parcial. Cada uma dessas ausências está declarada no README com o motivo — nenhuma
está escondida.
Os números
Nada aqui foi estimado. Tudo é medido na integração contínua, e o comando para reproduzir
está ao lado de cada número no repositório.
Durabilidade
0
violações de atomicidade em 20.000 quedas de energia
simuladas por noite.
O que está modelado é perda de energia, não processo morto. Processo morto perde os
próprios buffers, mas o que já chegou ao sistema operacional é gravado de qualquer jeito
— o teste passaria mesmo sem a regra WAL existir. Aqui, só o que passou por
fsync sobrevive.
Compatibilidade
9.172 / 9.172
asserções do corpus do próprio SQLite, aprovadas. Zero reprovadas.
O número que anda junto: 35,1% do corpus conseguiu rodar. O resto pede
SQL que este banco não tem. Publicar 100% escondendo isso seria mentira estatística, e as
ausências saem listadas e ranqueadas no relatório.
Desempenho
9× a 13×
mais lento que o SQLite na escrita, com durabilidade igualada.
Publicado perdendo, de propósito. Mas 1,4× quando cada linha é uma
transação: onde o fsync domina, os motores convergem — e é essa linha que
valida a medição inteira.
Cada seta é uma transformação entre estruturas de dados, testável sozinha. O
EXPLAIN existe desde o começo porque planner que não mostra o que decidiu é
planner que não dá para conferir — experimente no console acima.
Por que existe
Quase todo mundo que escreve backend usa banco de dados todo dia sem saber o que acontece
entre o INSERT e o dado estar seguro no disco. A pergunta que move o projeto é
estreita: o que acontece se a luz cair exatamente no meio de um COMMIT?
A resposta certa é que ou a transação inteira aconteceu, ou nenhuma parte dela aconteceu.
Nunca metade. Escrever o banco foi a parte fácil; provar que ele não perde seus dados foi o
projeto.