Iedereen een fijn weekend! Uitnodiging voor een gratis demo-les , geleid door Andrej Buranov — specialist in UNIX-systemen bij Mail.Ru Group. Ook publiceren we een artikel van Jonathan Corbet — Executive Editor bij LWN.net.
Gejournaliseerde bestandssystemen beloven systeembeheerders te ontlasten van problemen met schijfbeschadiging bij systeemfouten. Zelfs zonder het uitvoeren van een controle op de integriteit van het bestandssysteem. Hoewel het in de praktijk natuurlijk iets ingewikkelder is. En zoals recentelijk besproken, misschien zelfs ingewikkelder dan velen van ons denken, aangezien de waarborging van de integriteit van gejournaliseerde bestandssystemen invloed heeft op de prestaties.
Een bestandssysteem zoals ext3 gebruikt een aparte ruimte op de schijf, die een journal wordt genoemd. Wanneer veranderingen aan de metadata van het bestandssysteem worden aangebracht, worden deze veranderingen eerst in het journal geschreven zonder de rest van het bestandssysteem te wijzigen. Na het schrijven van alle wijzigingen in het journal wordt er een ‘commit block’ toegevoegd, wat aangeeft dat de transactie is voltooid. Pas na het schrijven van het commit block wordt de transactie vastgelegd en worden de gewijzigde metadata op de schijf geschreven. Als het systeem op enig moment uitvalt, kan met behulp van de informatie in het journal veilig worden afgesloten en kan schade aan het bestandssysteem worden voorkomen, omdat slechts een deel van de metadata is bijgewerkt.
Er is echter één probleem: de code van het bestandssysteem moet er absoluut zeker van zijn dat alle informatie over de transactie al in het journal is gekomen voordat het commit block wordt geschreven. Het is niet voldoende om operaties in de juiste volgorde vast te leggen — moderne schijven ondersteunen grote interne caches en herschikken operaties voor een betere prestaties. Daarom moet er voorafgaand aan het commit block expliciet worden aangegeven dat alle gegevens van het journal naar de schijf moeten worden overgebracht. Als het commit block eerder wordt geschreven, kan het journal beschadigd raken. Om dit probleem op te lossen worden barrières gebruikt. In wezen voorkomt een barrière dat er blokken na de barrière worden geschreven totdat alle blokken die vóór de barrière zijn geschreven, naar de schijf zijn overgebracht. Door barrières te gebruiken, waarborgen bestandssystemen de consistentie van bestandstructuren.
Maar er is nog een probleem: de bestandsystemen ext3 en ext4 gebruiken standaard geen barrières. Er is een optie, maar als de administrator deze niet expliciet inschakelt, werken deze bestandsystemen zonder barrières, hoewel in sommige distributies (bijvoorbeeld SUSE) de standaardinstellingen anders zijn. Eric Sandeen heeft onlangs besloten dat deze situatie moet veranderen en , die de standaardinstellingen voor ext3 en ext4 aanpast. En toen begon de heftige discussie.
Andrew Morton heeft zeer uitvoerig , waarom de standaardwaarde precies zo is:
De vorige keer dat we dit probeerden, daalde de prestaties bij veel belasting met 30%, dus ik heb al die patches in paniek weggegooid. Ik denk dat we dit niet kunnen doen en de prestaties van alle machines zo ernstig kunnen vertragen…
Er zijn geen ideale oplossingen, en ik neig ertoe om deze slapende hond niet te wakker te maken en de standaardinstellingen over te laten aan de ontwikkelaars van de distributies.
Daarom zijn barrières standaard uitgeschakeld, omdat ze de prestaties ernstig beïnvloeden. Bovendien worden bestandsystemen met succes zonder barrières gebruikt. Meldingen van beschadigingen van het ext3-bestandssysteem zijn zeldzaam en opmerkelijk.
Maar het is niet alleen maar geluk. Ted Ts’o heeft te maken met het feit dat de journalen van ext3 / ext4 meestal continu zijn. Ten eerste probeert de besturingssystemen om dit continu te maken. Ten tweede wordt het journal meestal tegelijk met het bestandsysteem aangemaakt, wanneer er gemakkelijk een continuere ruimte te vinden is. Continuïteit en ordening zijn niet alleen nuttig voor de prestaties, maar ook om herordening te voorkomen. Gewoonlijk wordt de commit-blok direct na de andere gegevens in het journal geplaatst, waardoor de schijf geen reden heeft om te herordenen. De commit-blok wordt van nature meteen na de andere journalrecords op de schijf geschreven.
Toch beweert niemand dat het altijd zo zal zijn. Datadisk kunnen zich anders gedragen. Bovendien fungeren journals als een ringbuffer. Daarom, wanneer een transactie aan het einde van het journal wordt geschreven, kan de commit-blok zich in een eerdere blok bevinden, vóór andere journalrecords. Dus de kans op beschadiging is altijd aanwezig. In feite heeft Chris Mason hier een Er is geen twijfel dat werken zonder barrières minder veilig is dan met barrières.
Als je bereid bent om de impact op de prestaties te accepteren, kun je barrières inschakelen. Dit geldt natuurlijk als je bestandssysteem niet is gebaseerd op LVM (zoals in sommige distributies standaard het geval is). Blijkbaar ondersteunt de device mapper geen barrières. In andere gevallen zou het goed zijn om de prestatievermindering te verminderen. En het lijkt erop dat dit mogelijk is.
De huidige implementatie van ext3 (wanneer barrières zijn ingeschakeld) voert voor elke transactie de volgende reeks acties uit:
Gegevens worden in het logboek geschreven.
Een barrière wordt uitgevoerd.
De commit-blok wordt geschreven.
De volgende barrière wordt uitgevoerd.
Later worden de metadata op de schijf gewist.
In ext4 kan de eerste barrière (stap 2) worden overgeslagen, omdat het ext4-bestandssysteem controlecijfers in het logboek ondersteunt.
Als de loggegevens en commit-blok worden herschikt, en de operatie wordt onderbroken door een fout, dan komt het controlecijfer in het logboek niet overeen met dat in het commit-blok, en de transactie zal worden afgewezen.
Chris Mason , wat zou betekenen dat het "over het algemeen veilig" zou zijn om deze barrière ook in ext3 te verwijderen, met mogelijk een uitzondering wanneer het logboek het einde bereikt en opnieuw vanaf het begin begint te schrijven.
Een ander idee om de prestaties te versnellen, is om barrière-operaties uit te stellen wanneer dat mogelijk is. Als er geen dringende noodzaak is om gegevens onmiddellijk op de schijf te wissen, kan men meerdere transacties in het logboek aanmaken en deze met één barrière op de schijf wissen.
Er is ook enige potentie voor verbeteringen door acties zorgvuldig te ordenen, zodat barrières (die doorgaans worden uitgevoerd als aanvragen om 'alle uitgestelde acties naar de schijf te schrijven') geen blokken afdwingen die niet geordend hoeven te zijn.
Het lijkt tijd om na te denken over hoe de kosten van barrières acceptabel te maken. Ted Ts'o lijkt :
Ik denk dat we barrières in ext3/4 moeten inschakelen en vervolgens moeten werken aan het verminderen van de overhead in ext4/jbd2. Waarschijnlijk werkt de overgrote meerderheid van de systemen niet onder omstandigheden zoals die Chris gebruikte om het probleem aan te tonen, en de veiligheid van het bestandssysteem moet prioriteit krijgen.
Gezond verstand zegt me dat deze hond niet meer slaapt en waarschijnlijk enige tijd zal blaffen. Dit kan voor sommige buren verontrustend zijn, maar het is beter dan haar te laten bijten.
Bent u geïnteresseerd in deze richting? Schrijf u in voor een gratis demo-les en neem deel aan de uitzending , gepresenteerd door Pavel Vikiryuk — operator van een MVNO, DevOps-engineer.
Bron: habr.com
