MongoDB – O que é journaling e por que isto é importante?
- Postado por Adriano Bonacin
- Categorias mongodb
- Data 24/01/2022
- Comentários 0 comentário
Estávamos falando de ReplicaSet, como criar, como obter o status, como trocar papéis e afins. Agora vamos dar uma pausa no HandsOn e falar um pouco de conceitos. O primeiro será o journaling, que é fundamental para que o MongoDB consiga garantir o que chamamos de durabilidade da transação. Há uma infinidade de opções para customizar e tunar seu DB (veja a documentação), mas aqui não vamos focar nisso. Por enquanto só vamos discutir o que é isso.
Journaling
A maioria dos bancos de dados possuem uma estrutura que garantem que toda transação commitada não seja perdida mesmo em caso de crash. Você pode até usar alguma engine específica ou configuração que ignora isso, normalmente para obter maior performance, mas por default eles sempre vem ativa.
Esta estrutura é chamada de log e escrita de forma sequencial em disco, um artifício para que seja um pouco mais rápido, principalmente em discos rotacionais. O termo que você vai encontrar por aí é: “write ahead logging” – WAL. No Oracle chamamos de REDO, no MSSQL de TRANSACTION LOG, no Cassandra de COMMITLOG, no Postgres de WAL, no MySQL de REDO e aqui no MongoDB vamos chamar de Journal.
Por que usar esta estrutura? Imagine um banco de dados com 10TB, com milhares de arquivos de dados. Você faz dois updates em diferentes collections. Teoricamente você precisa ir até os arquivos onde estão estes docs e fazer a alteração. Mas veja como isso pode ser complicado, ir lá no meio de um arquivo de 100GB e fazer uma alteração em um ponto específico. E se ao mesmo tempo em que ocorrem estes updates a gente também resolve inserir alguns outros docs. Ir lá no final do arquivo escrever alguns bytes. Tudo isso com o seu cliente esperando receber o ok (ack) do banco de dados. E se 30 pessoas estiverem fazendo o mesmo?
Para tentar diminuir o tempo do cliente esperando, o banco de dados registra estes updates, inserts e qualquer operação de escrita primeiro no log file (journal, redo, commitlog, transactlog, …). Normalmente estes arquivos de log já são prealocados no filesystem, para economizar mais um pouquinho de tempo. Uma vez registrado, ele envia o ok para o cliente.
Checkpoint
O dado ainda precisa chegar até os datafiles. O responsável por isso é um processo chamado checkpoint, que de tempos em tempos fica levando tudo que tem no log para os datafiles.
É importante notar que sempre há um gap entre o que temos no log e o que temos no datafile e que mesmo assim os bancos respondem com o dado atualizado sempre que requisitado e cada um implementa um mecanismo para tal. Isso quer dizer que em situações normais este gap não é um problema.
Crash recovery
Mas a vida não é feita só de situações normais, certo? Quando nosso DB cai de forma inesperada, ele fica com esse gap em aberto. Então o gap precisa ser resolvido na próxima vez que o banco subir, antes de estar disponível para a aplicação. Este processo de resolução deste gap, de enviar para os datafiles tudo que está somento nos logs, é o que chamamos de crash recovery ou instance recovery.