Ruimtetoewijzing in Firebird 2.1 en hoger
Vlad Khorsun, 20-OKT-2010
Vanaf het begin had Firebird geen regels voor het toewijzen van schijfruimte voor databasebestand(en). Het schrijft eenvoudigweg nieuw toegewezen pagina’s in een onbepaalde volgorde (vanwege afhankelijkheden tussen pagina’s om de strategie voor «zorgvuldig schrijven» te ondersteunen).
Deze aanpak is zeer eenvoudig, maar heeft enkele nadelen:
• vanwege de onbepaalde volgorde van schrijven kan er een situatie ontstaan waarin de paginacache veel vuile pagina’s bevat op het moment dat een nieuw toegewezen pagina moet worden geschreven, maar dit niet kan vanwege onvoldoende schijfruimte. In dergelijke gevallen gaan vaak alle andere vuile pagina’s verloren omdat beheerders er de voorkeur aan geven de database af te sluiten voordat ze schijfruimte vrijmaken. Dit leidt tot ernstige corruptie.
• het toewijzen van schijfruimte in relatief kleine blokken kan leiden tot aanzienlijke bestandsfragmentatie op bestandssysteemniveau en vermindert de prestaties van grote scans (bijvoorbeeld tijdens een back-up).
Met de nieuwe ODS 11.1 wijzigt Firebird zijn algoritme voor schijfruimtetoewijzing om corruptie bij onvoldoende schijfruimte te voorkomen en het bestandssysteem de kans te geven fragmentatie te vermijden. Deze wijzigingen worden hieronder beschreven.
a) Elke nieuw toegewezen pagina wordt onmiddellijk op schijf geschreven voordat deze aan de engine wordt teruggegeven. Als een pagina niet kan worden geschreven, vindt er geen toewijzing plaats, wordt de PIP-bit niet gewist en wordt een passende IO-fout gegenereerd. Deze fout kan niet tot corruptie leiden, omdat we de garantie hebben dat alle vuile pagina’s in de cache over toegewezen schijfruimte beschikken en veilig kunnen worden geschreven.
Deze wijziging zorgt voor één extra schrijfbewerking van elke nieuw toegewezen pagina vergeleken met het oude gedrag. Er wordt dus een prestatievermindering verwacht tijdens de groei van het databasebestand. Om deze vermindering te beperken, groepeert Firebird het schrijven van nieuw toegewezen pagina’s tot 128 KB per keer en houdt het het aantal «geïnitialiseerde» pagina’s bij in de PIP-header.
Opmerking: een nieuw toegewezen pagina wordt alleen twee keer op schijf geschreven als deze pagina voor de eerste keer wordt toegewezen. Dat wil zeggen: als een pagina is toegewezen, vrijgegeven en opnieuw toegewezen, wordt deze bij de tweede toewijzing niet twee keer geschreven.
b) Om bestandsfragmentatie te voorkomen, gebruikte Firebird de juiste API van het bestandssysteem om schijfruimte in relatief grote blokken vooraf toe te wijzen. Momenteel bestaat een dergelijke API alleen in Windows, maar deze is onlangs toegevoegd aan de Linux-API en kan in de toekomst worden geïmplementeerd in populaire bestandssystemen zoals ext2, enz. Deze functie is daarom momenteel alleen geïmplementeerd in Windows-builds van Firebird en kan in de toekomst worden geïmplementeerd in Linux-builds.
Voor een betere controle over de vooraf toegewezen schijfruimte is een nieuwe instelling in Firebird.conf geïntroduceerd: DatabaseGrowthIncrement. Dit is de bovengrens van de grootte van het vooraf toegewezen blok in bytes. De standaardwaarde is 128 MB. Wanneer de engine meer schijfruimte nodig heeft, wijst deze 1/16e van de reeds toegewezen ruimte toe, maar niet minder dan 128 KB en niet meer dan de waarde van DatabaseGrowthIncrement. Als DatabaseGrowthIncrement op nul wordt ingesteld, is vooraf toewijzen uitgeschakeld. Ruimte voor databaseschaduwbestanden wordt niet vooraf toegewezen.
Ook is vooraf toewijzen uitgeschakeld als de optie «No reserve» voor de database is ingesteld.
Opmerking: vooraf toewijzen helpt ook om corruptie bij onvoldoende schijfruimte te voorkomen - in dat geval is er een grote kans dat de database voldoende vooraf toegewezen ruimte heeft om te blijven werken totdat de beheerder schijfruimte vrijmaakt.
Auteur: Vlad Khorsun,