MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Il journaling di MongoDB garantisce la durabilità?

Pubblicazione di una nuova risposta per ripulire questo. Ho eseguito dei test e ho letto di nuovo il codice sorgente e sono sicuro che l'irritazione derivi da una frase sfortunata nella documentazione relativa al problema di scrittura. Con l'inserimento nel journal abilitato e j:true problema di scrittura, la scrittura è duratura e non vi è alcuna finestra misteriosa per la perdita di dati.

Anche se il journaling è attivo, c'è ancora la possibilità di perdere le scritture in MongoDB?

Sì, perché la durabilità dipende anche dalle singole operazioni che riguardano la scrittura.

"Per impostazione predefinita, la maggior parte delle scritture perse, ovvero quelle non effettuate sul journal, sono quelle effettuate negli ultimi 100 millisecondi."

Questo proviene da Manage Journaling, che indica che potresti perdere le scritture effettuate dall'ultima volta che il journal è stato scaricato su disco.

È corretto. Il journal viene svuotato da un thread separato in modo asincrono, quindi puoi perdere tutto dall'ultimo flush.

Se voglio una maggiore durata, "Per costringere mongod a impegnarsi più frequentemente nel diario, puoi specificare j:true . Quando un'operazione di scrittura con j:true è in attesa, mongod ridurrà journalCommitInterval a un terzo del valore impostato."

Questo ha irritato anche me. Ecco cosa significa:

Quando invii un'operazione di scrittura con j:true , non attiva immediatamente lo svuotamento del disco e non sul thread di rete. Questo ha senso, perché potrebbero esserci dozzine di applicazioni che parlano alla stessa istanza mongod. Se ogni applicazione utilizzasse molto il journaling, il db sarebbe molto lento perché esegue continuamente la sincronizzazione.

Invece, quello che succede è che il "thread di durabilità" prenderà tutti i commit del journal in sospeso e li scaricherà sul disco. Il thread è implementato in questo modo (commenta il mio):

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();

Quindi un j:true in sospeso l'operazione farà sì che il thread di commit del journal venga eseguito prima del normale e commetterà tutte le scritture in sospeso sul journal, comprese quelle che non hanno j:true impostato.

Anche in questo caso, sembra che lo svuotamento del journal su disco sia asincrono, quindi c'è ancora la possibilità di perdere le scritture. Mi sfugge qualcosa su come garantire che le scritture non vadano perse?

La scrittura (o getLastError comando) con un j:true problema di scrittura su journal attende che il thread di durabilità termini la sincronizzazione , quindi non c'è rischio di perdita di dati (per quanto il sistema operativo e l'hardware lo garantiscano).

La frase "Tuttavia, c'è una finestra tra i commit del journal quando l'operazione di scrittura non è completamente durevole" probabilmente si riferisce a un mongod in esecuzione con l'inserimento nel journal abilitato che accetta una scrittura che NON usa il j:true scrivi preoccupazione. In tal caso, c'è la possibilità che la scrittura venga persa dall'ultimo commit del journal.

Ho presentato una segnalazione di bug dei documenti per questo.