MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Garantiert MongoDB-Journaling Langlebigkeit?

Posten einer neuen Antwort, um dies zu bereinigen. Ich habe Tests durchgeführt und den Quellcode erneut gelesen, und ich bin mir sicher, dass die Irritation von einem unglücklichen Satz in der Dokumentation zum Schreiben von Bedenken stammt. Mit aktiviertem Journaling und j:true schreiben Bedenken, der Schreibvorgang ist dauerhaft und es gibt kein mysteriöses Fenster für Datenverlust.

Besteht auch bei aktiviertem Journaling die Möglichkeit, Schreibvorgänge in MongoDB zu verlieren?

Ja, denn die Haltbarkeit hängt auch von den einzelnen Schreibvorgängen ab.

"Standardmäßig sind die meisten verlorenen Schreibvorgänge, d. h. diejenigen, die nicht in das Journal vorgenommen wurden, diejenigen, die in den letzten 100 Millisekunden vorgenommen wurden."

Dies stammt von Manage Journaling, was darauf hinweist, dass Schreibvorgänge verloren gehen könnten, seit das Journal das letzte Mal auf die Festplatte geleert wurde.

Das ist richtig. Das Journal wird von einem separaten Thread asynchron geleert, sodass Sie alles seit der letzten Leerung verlieren können.

Wenn ich mehr Haltbarkeit möchte, "um Mongod zu zwingen, sich häufiger an das Journal zu binden, können Sie j:true angeben . Bei einem Schreibvorgang mit j:true anhängig ist, wird Mongod journalCommitInterval reduzieren auf ein Drittel des eingestellten Wertes."

Das hat mich auch irritiert. Das bedeutet Folgendes:

Wenn Sie eine Schreiboperation mit j:true senden , wird die Datenträgerspülung nicht sofort und nicht im Netzwerkthread ausgelöst. Das ist sinnvoll, da es Dutzende von Anwendungen geben könnte, die mit derselben Mongod-Instanz kommunizieren. Wenn jede Anwendung viel Journaling verwenden würde, wäre die DB sehr langsam, weil sie die ganze Zeit fsynct.

Stattdessen nimmt der „Haltbarkeits-Thread“ alle ausstehenden Journal-Commits und spült sie auf die Festplatte. Der Thread ist wie folgt implementiert (Kommentare von mir):

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

Also ein ausstehendes j:true Der Vorgang bewirkt, dass der Journal-Commit-Thread früher als normalerweise übergeben wird, und er wird alle ausstehenden Schreibvorgänge in das Journal schreiben, einschließlich derjenigen, die j:true nicht haben eingestellt.

Selbst in diesem Fall sieht es so aus, als ob das Leeren des Journals auf die Festplatte asynchron ist, sodass immer noch die Möglichkeit besteht, dass Schreibvorgänge verloren gehen. Übersehe ich etwas darüber, wie ich garantieren kann, dass Schreibvorgänge nicht verloren gehen?

Das Schreiben (oder das getLastError Befehl) mit einem j:true Journaled Write Concern wartet, bis der Dauerhaftigkeits-Thread die Synchronisierung beendet , daher besteht kein Risiko eines Datenverlusts (sofern das Betriebssystem und die Hardware dies garantieren).

Der Satz „Es gibt jedoch ein Fenster zwischen Journal-Commits, wenn die Schreiboperation nicht vollständig dauerhaft ist“ bezieht sich wahrscheinlich auf einen Mongod, der mit aktiviertem Journaling läuft und einen Schreibvorgang akzeptiert, der NICHT tut Verwenden Sie den j:true Anliegen schreiben. In diesem Fall besteht die Möglichkeit, dass der Schreibvorgang seit dem letzten Journal-Commit verloren geht.

Ich habe dafür einen Fehlerbericht in der Dokumentation eingereicht.