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

Garanterer MongoDB journaling holdbarhed?

Sender et nyt svar for at rydde op i dette. Jeg udførte test og læste kildekoden igen, og jeg er sikker på, at irritationen kommer fra en uheldig sætning i skrivebekymringsdokumentationen. Med journalføring aktiveret og j:true skrive bekymring, skrivningen er holdbar, og der er intet mystisk vindue for datatab.

Selvom journalføring er aktiveret, er der så stadig en chance for at miste skriverier i MongoDB?

Ja, for holdbarheden afhænger også af de enkelte operationer skriv bekymring.

"Som standard er det største omfang af tabte skrivninger, dvs. dem, der ikke er foretaget til journalen, dem, der er foretaget inden for de sidste 100 millisekunder."

Dette er fra Manage Journaling, som indikerer, at du kan miste skrivninger, der er foretaget siden sidste gang, journalen blev tømt til disken.

Det er korrekt. Journalen skylles asynkront af en separat tråd, så du kan miste alt siden sidste flush.

Hvis jeg vil have mere holdbarhed, "For at tvinge mongod til at forpligte sig til tidsskriftet oftere, kan du angive j:true . Når en skriveoperation med j:true afventer, vil mongod reducere journalCommitInterval til en tredjedel af den indstillede værdi."

Det irriterede mig også. Her er, hvad det betyder:

Når du sender en skriveoperation med j:true , udløser det ikke diskskylningen med det samme, og ikke på netværkstråden. Det giver mening, fordi der kan være snesevis af applikationer, der taler til den samme mongod-instans. Hvis alle programmer skulle bruge journalføring meget, ville db være meget langsom, fordi den fsynkroniserer hele tiden.

Det, der i stedet sker, er, at 'holdbarhedstråden' vil tage alle afventende journalforpligtelser og skylle dem til disken. Tråden er implementeret sådan her (kommentarer mine):

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

Så en afventende j:true operation vil få journal-commit-tråden til at commit tidligere, end den normalt ville, og den vil commite alle afventende skrivninger til journalen, inklusive dem, der ikke har j:true sæt.

Selv i dette tilfælde ser det ud til, at det er asynkront at skylle journalen til disken, så der er stadig en chance for at miste skrivninger. Mangler jeg noget om, hvordan man garanterer, at skrivninger ikke går tabt?

Skrivningen (eller getLastError kommando) med en j:true journaliseret skrive bekymring vil vente på, at holdbarhedstråden afslutter synkroniseringen , så der er ingen risiko for tab af data (så vidt OS og hardware garanterer det).

Sætningen "Der er dog et vindue mellem journalforpligtelser, når skriveoperationen ikke er fuldt holdbar" henviser sandsynligvis til en mongod, der kører med journalføring aktiveret, og som accepterer en skrivning, der IKKE gør. brug j:true skrive bekymring. I så fald er der en chance for, at skrivningen forsvinder siden sidste journalindføring.

Jeg indsendte en docs fejlrapport for dette.



  1. Sådan konverteres streng til objectId i LocalField for $lookup Mongodb

  2. Hvordan tjekker man for nul/nul i Redis' Lua cjson?

  3. Klasse 'MongoClient' blev ikke fundet

  4. Lagring af venskaber i MongoDB?