MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

O journaling do MongoDB garante durabilidade?


Postando uma nova resposta para limpar isso. Realizei testes e li o código-fonte novamente e tenho certeza que a irritação vem de uma frase infeliz na documentação do problema de gravação. Com journaling ativado e j:true preocupação de gravação, a gravação é durável e não há nenhuma janela misteriosa para perda de dados.

Mesmo que o journaling esteja ativado, ainda existe a chance de perder gravações no MongoDB?

Sim, porque a durabilidade também depende da preocupação de gravação das operações individuais.

"Por padrão, a maior extensão de gravações perdidas, ou seja, aquelas não feitas no diário, são aquelas feitas nos últimos 100 milissegundos."

Isso é de Gerenciar diário, que indica que você pode perder gravações feitas desde a última vez que o diário foi liberado para o disco.

Está correto. O diário é liberado por um encadeamento separado de forma assíncrona, portanto, você pode perder tudo desde a última liberação.

Se eu quiser mais durabilidade, "Para forçar o mongod a se comprometer com o diário com mais frequência, você pode especificar j:true . Quando uma operação de gravação com j:true está pendente, o mongod reduzirá journalCommitInterval a um terço do valor definido."

Isso também me irritou. Aqui está o que significa:

Quando você envia uma operação de gravação com j:true , ele não acionará a liberação do disco imediatamente e não no thread de rede. Isso faz sentido, porque pode haver dezenas de aplicativos conversando com a mesma instância mongod. Se todos os aplicativos usassem muito o journaling, o banco de dados seria muito lento porque está sincronizando o tempo todo.

Em vez disso, o que acontece é que o 'thread de durabilidade' pegará todas as confirmações de diário pendentes e as liberará para o disco. O thread é implementado assim (comentários meus):
sleepmillis(oneThird); //dur.cpp, line 801
for( unsigned i = 1; i <= 2; i++ ) {
  // break, if any j:true write is pending
  if( commitJob._notify.nWaiting() )
    break;
  // or the number of bytes is greater than some threshold
  if( commitJob.bytes() > UncommittedBytesLimit / 2  )
    break;
  // otherwise, sleep another third
  sleepmillis(oneThird);
}

// fsync all pending writes                                      
durThreadGroupCommit();

Portanto, um j:true pendente operação fará com que o thread de confirmação do diário seja confirmado mais cedo do que normalmente faria e confirmará todas as gravações pendentes no diário, incluindo aquelas que não têm j:true definir.

Mesmo nesse caso, parece que a liberação do diário para o disco é assíncrona, portanto, ainda há uma chance de perder gravações. Estou faltando algo sobre como garantir que as gravações não sejam perdidas?

A escrita (ou o getLastError comando) com um j:true preocupação de gravação em diário aguardará o thread de durabilidade terminar a sincronização , portanto, não há risco de perda de dados (desde que o sistema operacional e o hardware garantam isso).

A frase "No entanto, há uma janela entre os commits de diário quando a operação de gravação não é totalmente durável" provavelmente se refere a um mongod em execução com o journaling ativado que aceita uma gravação que NÃO use o j:true escreva preocupação. Nesse caso, há uma chance de a gravação se perder desde o último commit do diário.

Eu arquivei um relatório de bug docs para isso.