Atomowość i odzyskiwanie danych
AtomicFilesystem::write_atomic() zapisuje dane do pliku tymczasowego, opróżnia bufor i wywołuje
fsync dla tego uchwytu pliku, zmienia nazwę pliku na docelową, a następnie próbuje wywołać fsync
dla katalogu nadrzędnego. Nieudany zapis usuwa własny plik tymczasowy.
Instancje magazynu zapisujące dane rejestrują znacznik dla procesu w
.storh/writers/ i usuwają go przy poprawnym zamknięciu. Podczas otwierania magazyn sprawdza
te znaczniki: jeśli właściciel każdego z nich nadal działa (lub nie ma żadnych znaczników), otwarcie ma stały czas działania; znacznik, którego proces-właściciel już nie działa, oznacza awarię zapisującego procesu, więc podczas otwierania wykonywane jest skanowanie kolekcji w poszukiwaniu osieroconych plików tymczasowych i usuwany jest nieaktualny znacznik. repair() zawsze wykonuje skanowanie.
Naprawa DocStore poddaje kwarantannie uszkodzone lub ucięte pliki rekordów w
.storh/corrupt/ i odbudowuje indeksy wtórne na podstawie pozostałych prawidłowych
rekordów. Weryfikacja DocStore porównuje również pliki indeksów z pełnym skanem rekordów, aby zgłosić brakujące lub nieaktualne wpisy indeksu, zanim zostaną uznane za prawidłowe.
Silniki tylko do dopisywania opróżniają bufory i wykonują fsync na uchwytach plików dziennika, zanim uznają zdarzenia za zapisane w pamięci. Trwałość danych po utracie zasilania nadal zależy od tego, czy bazowy system plików i opcje montowania poprawnie obsługują synchronizację plików i katalogów.
Dziennik segmentowany zapisuje każdy wiersz w postaci:
<byte-length>\t<xxh32>\t<json>\n
Odczyt sprawdza długość bajtową i sumę kontrolną. Odzyskiwanie skanuje każdy segment i skraca plik do ostatniego kompletnego, prawidłowego wiersza, usuwając niekompletne zapisy na końcu. Weryfikacja porównuje aktywny indeks stanu pochodnego z niezależnym odtworzeniem segmentów, aby zgłosić stan zmieniony z zewnątrz lub nieaktualny, zanim naprawa go odbuduje.
Weryfikacja kolejki dekoduje każde trwałe zdarzenie kolejki i porównuje bieżący
stan zadań oczekujących, przetwarzanych i ukończonych, ich ładunków oraz kolejności przejęcia z niezależnym
odtworzeniem dziennika. Naprawa odbudowuje ten stan z queue.log i usuwa niekompletne
zdarzenia na końcu. Procesy przejmowania zadań i ich kończenia blokują kolejkę podczas synchronizacji z
trwałym dziennikiem, dzięki czemu wiele procesów roboczych nie przejmie tego samego oczekującego zadania.
Kompaktowanie zapisuje nowe pliki segmentów compact-*, a następnie aktualizuje manifest.
Jeśli proces zakończy się przed podmianą manifestu, ponowne otwarcie usuwa niepowiązane
wyjście kompaktowania i kontynuuje pracę ze starym manifestem. Zakończone operacje
kompaktowania celowo pozostawiają stare, zamknięte segmenty, aby czytelnicy, którzy już je odczytują,
nadal mogli z nich korzystać.