Ga naar de inhoud

Atomiciteit en herstel

AtomicFilesystem::write_atomic() schrijft naar een tijdelijk bestand, flush't en voert fsync uit op die bestandsingang, hernoemt het bestand naar het doelpad en probeert fsync uit te voeren op de bovenliggende map. Bij mislukte schrijfbewerkingen wordt het eigen tijdelijke bestand verwijderd.

Schrijvende store-instanties registreren een markering per proces onder .storh/writers/ en verwijderen die bij een nette afsluiting. Bij het openen van een store worden deze markeringen gecontroleerd: als de eigenaar van elke markering nog actief is (of er geen zijn), is het openen constant in tijd; een markering waarvan het eigenaarproces niet meer bestaat, betekent dat een schrijver is gecrasht. Het openen doorloopt dan de collectie om verweesde tijdelijke bestanden op te ruimen en verwijdert de verouderde markering. repair() voert altijd een scan uit.

Bij herstel zet DocStore beschadigde of afgebroken recordbestanden in quarantaine onder .storh/corrupt/ en bouwt secundaire indexen opnieuw op aan de hand van de resterende geldige records. Bij verificatie vergelijkt DocStore de indexbestanden ook met een volledige scan van records, zodat ontbrekende of verouderde indexvermeldingen worden gemeld voordat ze als geldig kunnen worden beschouwd.

Append-only-engines flushen hun logbestandshandles en voeren fsync uit voordat ze gebeurtenissen als vastgelegd in het geheugen beschouwen. Duurzaamheid bij stroomuitval blijft afhankelijk van de onderliggende bestandssystemen en aankoppelopties die synchronisaties van bestanden en mappen respecteren.

Het gesegmenteerde log schrijft elke regel als volgt:

Text
<byte-length>\t<xxh32>\t<json>\n

Bij het lezen worden de bytelengte en checksum gecontroleerd. Herstel scant elk segment en kapt het bestand af na de laatste volledige geldige regel, waarmee onvolledige afsluitende schrijfbewerkingen worden verwijderd. Verificatie vergelijkt de actieve afgeleide statusindex met een onafhankelijke replay van segmenten, zodat extern gewijzigde of verouderde status wordt gemeld voordat herstel deze opnieuw opbouwt.

Bij queueverificatie wordt elke duurzame queuegebeurtenis gedecodeerd en de huidige status van wachtrij, verwerking, voltooiing, payload en claimvolgorde vergeleken met een onafhankelijke logreplay. Herstel bouwt die status opnieuw op vanuit queue.log en kapt onvolledige afsluitende gebeurtenissen af. Bij claims en voltooiingen wordt de queuelock vastgehouden terwijl er vanuit het duurzame log wordt gesynchroniseerd, zodat meerdere workerprocessen niet dezelfde wachtende taak claimen.

Compactie schrijft nieuwe compact-*-segmentbestanden en werkt daarna het manifest bij. Als een proces stopt voordat het manifest is omgewisseld, verwijdert opnieuw openen niet-gerefereerde compactie-uitvoer en gaat verder met het oude manifest. Voltooide compacties laten oude verzegelde segmenten bewust staan, zodat lezers die er al uit lezen geldig blijven.