Allocazione dello spazio in Firebird 2.1 e versioni successive
Vlad Khorsun, 20-OCT-2010
Fin dall’inizio, Firebird non aveva regole su come allocare spazio su disco per i file di database. Scrive semplicemente le nuove pagine allocate in un ordine non determinato (a causa delle dipendenze tra le pagine per servire la strategia di «scrittura accurata»).
Questo approccio è molto semplice ma presenta alcuni svantaggi:
• a causa dell’ordine non determinato delle scritture, può verificarsi una situazione in cui la cache delle pagine contiene molte pagine sporche nel momento in cui una nuova pagina allocata deve essere scritta ma non può esserlo per mancanza di spazio su disco. In tali casi, spesso tutte le altre pagine sporche vengono perse perché gli amministratori preferiscono spegnere il database prima di liberare spazio su disco. Questo porta a gravi corruzioni.
• allocare spazio su disco in blocchi relativamente piccoli può portare a una significativa frammentazione dei file a livello di file system e ridurre le prestazioni delle scansioni di grandi dimensioni (ad esempio durante il backup).
Utilizzando il nuovo ODS 11.1, Firebird modifica il suo algoritmo di allocazione dello spazio su disco per evitare corruzioni in condizioni di spazio su disco esaurito e per dare al file system la possibilità di evitare la frammentazione. Queste modifiche sono descritte di seguito.
a) Ogni pagina appena allocata viene scritta su disco immediatamente prima di essere restituita al motore. Se la pagina non può essere scritta, l’allocazione non avviene, il bit PIP non viene cancellato e viene sollevato un errore di I/O appropriato. Questo errore non può portare a corruzioni poiché abbiamo la garanzia che tutte le pagine sporche nella cache hanno spazio su disco allocato e possono essere scritte in sicurezza.
Questa modifica comporta una scrittura aggiuntiva di ogni pagina appena allocata rispetto al comportamento precedente. Quindi è prevista una penalizzazione delle prestazioni durante la crescita del file di database. Per ridurre questa penalizzazione, Firebird raggruppa le scritture delle pagine appena allocate fino a 128KB alla volta e tiene traccia del numero di pagine «inizializzate» nell’intestazione PIP.
Nota: la pagina appena allocata verrà scritta su disco due volte solo se questa pagina viene allocata per la prima volta. Cioè, se una pagina è stata allocata, liberata e allocata di nuovo, non verrà scritta due volte alla seconda allocazione.
b) Per evitare la frammentazione dei file, Firebird ha utilizzato l’API appropriata del file system per preallocare spazio su disco in blocchi relativamente grandi. Attualmente tale API esiste solo in Windows, ma è stata recentemente aggiunta all’API Linux e potrebbe essere implementata in file system popolari come ext2, ecc. in futuro. Quindi questa funzionalità è attualmente implementata solo nelle build Windows di Firebird e potrebbe essere implementata nelle build Linux in futuro.
Per un migliore controllo della preallocazione dello spazio su disco, è stata introdotta una nuova impostazione in Firebird.conf: DatabaseGrowthIncrement. Questo è il limite superiore della dimensione del blocco di preallocazione in byte. Il valore predefinito è 128MB. Quando il motore necessita di più spazio su disco, alloca 1/16 dello spazio già allocato, ma non meno di 128KB e non più del valore di DatabaseGrowthIncrement. Se DatabaseGrowthIncrement è impostato a zero, la preallocazione è disabilitata. Lo spazio per i file shadow del database non viene preallocato.
Inoltre, la preallocazione è disabilitata se l’opzione «No reserve» è impostata per il database.
Nota: la preallocazione consente anche di evitare corruzioni in condizione di spazio su disco esaurito - in tal caso, c’è una grande possibilità che il database abbia abbastanza spazio preallocato per operare fino a quando l’amministratore non libera spazio su disco.
Autore: Vlad Khorsun,