MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Czy księgowanie MongoDB gwarantuje trwałość?

Opublikowanie nowej odpowiedzi, aby to uporządkować. Przeprowadziłem testy i ponownie przeczytałem kod źródłowy i jestem pewien, że irytację bierze się z niefortunnego zdania w dokumentacji dotyczącej zapisu. Z włączonym dziennikiem i j:true problem związany z zapisem, zapis jest trwały i nie ma tajemniczego okna utraty danych.

Nawet jeśli dziennik jest włączony, czy nadal istnieje szansa na utratę zapisów w MongoDB?

Tak, ponieważ trwałość zależy również od poszczególnych operacji napisz obawy.

„Domyślnie największy zakres utraconych zapisów, tj. tych, które nie zostały zapisane w dzienniku, to te, które powstały w ciągu ostatnich 100 milisekund”.

Pochodzi z Zarządzaj dziennikami, co oznacza, że ​​możesz utracić zapisy dokonane od czasu ostatniego opróżnienia dziennika na dysk.

To jest poprawne. Dziennik jest opróżniany przez oddzielny wątek asynchronicznie, więc możesz stracić wszystko od ostatniego opróżnienia.

Jeśli chcę większej trwałości, „Aby zmusić mongoda do częstszego zatwierdzania dziennika, możesz określić j:true . Gdy operacja zapisu z j:true jest w toku, mongod zmniejszy journalCommitInterval do jednej trzeciej ustawionej wartości."

Mnie też to irytowało. Oto, co to oznacza:

Kiedy wysyłasz operację zapisu z j:true , nie powoduje natychmiastowego opróżnienia dysku, a nie w wątku sieciowym. Ma to sens, ponieważ mogą istnieć dziesiątki aplikacji komunikujących się z tą samą instancją mongod. Gdyby każda aplikacja często korzystała z kronikowania, baza danych byłaby bardzo wolna, ponieważ cały czas fsynchronizowałaby.

Zamiast tego dzieje się tak, że „wątek trwałości” zabierze wszystkie oczekujące zatwierdzenia dziennika i opróżni je na dysk. Wątek jest zaimplementowany w ten sposób (moje komentarze):

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

Tak więc oczekujący j:true operacja spowoduje, że wątek zatwierdzenia dziennika zostanie zatwierdzony wcześniej niż normalnie i zatwierdzi wszystkie oczekujące zapisy do dziennika, w tym te, które nie mają j:true zestaw.

Nawet w tym przypadku wygląda na to, że opróżnianie dziennika na dysk jest asynchroniczne, więc nadal istnieje szansa na utratę zapisów. Czy brakuje mi czegoś o tym, jak zagwarantować, że zapisy nie zostaną utracone?

Write (lub getLastError polecenie) z j:true obawy dotyczące zapisu w dzienniku poczekają na zakończenie synchronizacji wątku trwałości , więc nie ma ryzyka utraty danych (o ile gwarantuje to system operacyjny i sprzęt).

Zdanie „Jednakże istnieje okno między zatwierdzeniami dziennika, gdy operacja zapisu nie jest w pełni trwała” prawdopodobnie odnosi się do mongoda działającego z włączonym dziennikiem, który akceptuje zapis, który NIE użyj j:true napisz troskę. W takim przypadku istnieje szansa, że ​​zapis zostanie utracony od czasu ostatniego zatwierdzenia dziennika.

Zgłosiłem w tym celu raport o błędzie w dokumentacji.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB przejmuje mLab  —  Jakie są różne alternatywy hostingu MongoDB?

  2. MongoError:nie udało się połączyć z serwerem przy pierwszym połączeniu

  3. PHP nie może znaleźć sterownika MongoDB

  4. Indeks poddokumentów w mongo

  5. Sortowanie bez rozróżniania wielkości liter w MongoDB