MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Журналирането на MongoDB гарантира ли издръжливост?

Публикуване на нов отговор за изчистване на това. Направих тестове и прочетох отново изходния код и съм сигурен, че раздразнението идва от едно злополучно изречение в документацията за загриженост за писане. С активирано водене на журнал и j:true притеснение при запис, записът е издръжлив и няма мистериозен прозорец за загуба на данни.

Дори ако журналирането е включено, все още има ли шанс да загубите записи в MongoDB?

Да, защото издръжливостта зависи и от индивидуалните операции за запис.

„По подразбиране най-голямата част от загубените записи, т.е. тези, които не са направени в дневника, са тези, направени през последните 100 милисекунди.“

Това е от Manage Journaling, което показва, че може да загубите записи, направени след последния път, когато дневникът е бил изтрит на диск.

Това е вярно. Дневникът се прочиства от отделна нишка асинхронно, така че можете да загубите всичко след последното изчистване.

Ако искам повече издръжливост, "За да принудите mongod да се ангажира по-често в дневника, можете да посочите j:true . При операция на запис с j:true е в очакване, mongod ще намали journalCommitInterval до една трета от зададената стойност."

Това също ме дразнеше. Ето какво означава това:

Когато изпращате операция за запис с j:true , не задейства незабавно изчистване на диска, а не в мрежовата нишка. Това има смисъл, защото може да има десетки приложения, разговарящи с един и същ mongod екземпляр. Ако всяко приложение използваше много журналиране, db би бил много бавен, защото се синхронизира през цялото време.

Вместо това, това, което се случва, е, че „нишката за издръжливост“ ще вземе всички чакащи ангажименти в дневника и ще ги изхвърли на диск. Нишката е реализирана по следния начин (коментари ми):

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

Така че чакащ j:true операцията ще накара нишката за запис на дневника да се извърши по-рано, отколкото обикновено, и ще запише всички чакащи записи в дневника, включително тези, които нямат j:true зададено.

Дори в този случай изглежда, че изтриването на дневника на диск е асинхронно, така че все още има шанс да загубите записи. Пропускам ли нещо за това как да гарантирам, че записите няма да бъдат загубени?

Записът (или getLastError команда) с j:true притеснения за запис в журнал ще изчака нишката за издръжливост да завърши синхронизирането , така че няма риск от загуба на данни (доколкото ОС и хардуер гарантират това).

Изречението „Въпреки това има прозорец между записванията в журнал, когато операцията по запис не е напълно издръжлива“ вероятно се отнася до mongod, работещ с активирано журналиране, който приема запис, който НЕ използвайте j:true пишете загриженост. В този случай има вероятност записът да се изгуби след последното записване на журнала.

Подадох доклад за грешка в документите за това.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Какво е полето __v в Mongoose

  2. $strLenBytes срещу $strLenCP в MongoDB:Каква е разликата?

  3. MongoDB $in оператор на конвейера за агрегация

  4. Как да правя необработени mongodb операции в mongoose?

  5. MongoDB:проверете връзката с DB