sql >> Base de Datos >  >> NoSQL >> MongoDB

¿MongoDB journaling garantiza durabilidad?

Publicando una nueva respuesta para limpiar esto. Realicé pruebas y leí el código fuente nuevamente y estoy seguro de que la irritación proviene de una oración desafortunada en la documentación de preocupación de escritura. Con registro en diario habilitado y j:true problema de escritura, la escritura es duradera y no hay una ventana misteriosa para la pérdida de datos.

Incluso si el diario está activado, ¿aún existe la posibilidad de perder escrituras en MongoDB?

Sí, porque la durabilidad también depende de las operaciones individuales. Escriba la preocupación.

"De forma predeterminada, la mayor parte de las escrituras perdidas, es decir, las que no se realizaron en el diario, son las realizadas en los últimos 100 milisegundos".

Esto es de Manage Journaling, lo que indica que podría perder las escrituras realizadas desde la última vez que se vació el diario en el disco.

Eso es correcto. El diario se vacía mediante un subproceso independiente de forma asincrónica, por lo que puede perder todo desde el último lavado.

Si quiero más durabilidad, "Para obligar a mongod a comprometerse con el diario con más frecuencia, puede especificar j:true . Cuando una operación de escritura con j:true está pendiente, mongod reducirá journalCommitInterval a un tercio del valor fijado."

Esto también me irritó. Esto es lo que significa:

Cuando envía una operación de escritura con j:true , no activa el vaciado del disco inmediatamente y no en el subproceso de la red. Eso tiene sentido, porque podría haber docenas de aplicaciones hablando con la misma instancia de mongod. Si todas las aplicaciones usaran mucho el registro en diario, la base de datos sería muy lenta porque se está sincronizando todo el tiempo.

En cambio, lo que sucede es que el 'hilo de durabilidad' tomará todas las confirmaciones pendientes del diario y las descargará en el disco. El hilo se implementa así (comentarios míos):

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

Así que un j:true pendiente La operación hará que el subproceso de confirmación del diario se confirme antes de lo normal y confirmará todas las escrituras pendientes en el diario, incluidas aquellas que no tienen j:true establecer.

Incluso en este caso, parece que vaciar el diario en el disco es asíncrono, por lo que aún existe la posibilidad de perder escrituras. ¿Me estoy perdiendo algo sobre cómo garantizar que las escrituras no se pierdan?

La escritura (o el getLastError comando) con un j:true preocupación de escritura registrada esperará a que el subproceso de durabilidad termine de sincronizarse , por lo que no hay riesgo de pérdida de datos (en la medida en que el sistema operativo y el hardware lo garanticen).

La oración "Sin embargo, hay una ventana entre las confirmaciones del diario cuando la operación de escritura no es completamente duradera" probablemente se refiere a un mongod que se ejecuta con el diario habilitado que acepta una escritura que NO usa el j:true escribir preocupación. En ese caso, existe la posibilidad de que se pierda la escritura desde la última confirmación del diario.

Presenté un informe de error de documentos para esto.