Allocation de l'espace dans Firebird 2.1 et versions ultérieures
Vlad Khorsun, 20-OCT-2010
Depuis le début, Firebird n’avait aucune règle concernant l’allocation d’espace disque pour les fichiers de base de données. Il écrit simplement les nouvelles pages allouées dans un ordre non déterminé (en raison des dépendances entre les pages pour servir la stratégie d’« écriture prudente »).
Cette approche est très simple mais présente quelques inconvénients :
• en raison de l’ordre non déterminé des écritures, il peut y avoir une situation où le cache de pages contient de nombreuses pages modifiées au moment où une nouvelle page allouée doit être écrite mais ne peut pas l’être en raison d’un manque d’espace disque. Dans de tels cas, toutes les autres pages modifiées sont souvent perdues car les administrateurs préfèrent arrêter la base de données avant de libérer de l’espace disque. Cela entraîne de graves corruptions.
• l’allocation d’espace disque par blocs relativement petits peut entraîner une fragmentation importante des fichiers au niveau du système de fichiers et réduire les performances des grandes analyses (par exemple lors d’une sauvegarde).
Avec le nouvel ODS 11.1, Firebird modifie son algorithme d’allocation d’espace disque pour éviter les corruptions en cas de manque d’espace disque et pour donner au système de fichiers une chance d’éviter la fragmentation. Ces modifications sont décrites ci-dessous.
a) Chaque nouvelle page allouée est écrite sur le disque immédiatement avant de revenir au moteur. Si la page ne peut pas être écrite, l’allocation ne se produit pas, le bit PIP n’est pas effacé et une erreur d’E/S appropriée est levée. Cette erreur ne peut pas entraîner de corruptions car nous avons la garantie que toutes les pages modifiées en cache disposent d’espace disque alloué et peuvent être écrites en toute sécurité.
Ce changement entraîne une écriture supplémentaire de chaque nouvelle page allouée par rapport à l’ancien comportement. Une pénalité de performance est donc attendue pendant la croissance du fichier de base de données. Pour réduire cette pénalité, Firebird regroupe les écritures des nouvelles pages allouées jusqu’à 128 Ko à la fois et suit le nombre de pages « initialisées » dans l’en-tête PIP.
Remarque : une page nouvellement allouée ne sera écrite deux fois sur le disque que si cette page est allouée pour la première fois. C’est-à-dire que si une page a été allouée, libérée puis allouée à nouveau, elle ne sera pas écrite deux fois lors de la seconde allocation.
b) Pour éviter la fragmentation des fichiers, Firebird a utilisé l’API appropriée du système de fichiers pour préallouer l’espace disque par blocs relativement grands. Actuellement, une telle API n’existe que sous Windows, mais elle a récemment été ajoutée à l’API Linux et pourrait être implémentée dans des systèmes de fichiers populaires tels que ext2, etc. à l’avenir. Cette fonctionnalité n’est donc actuellement implémentée que dans les versions Windows de Firebird et pourrait l’être dans les versions Linux à l’avenir.
Pour un meilleur contrôle de la préallocation d’espace disque, un nouveau paramètre a été introduit dans Firebird.conf : DatabaseGrowthIncrement. Il s’agit de la limite supérieure de la taille du bloc de préallocation en octets. La valeur par défaut est de 128 Mo. Lorsque le moteur a besoin de plus d’espace disque, il alloue 1/16e de l’espace déjà alloué, mais pas moins de 128 Ko et pas plus que la valeur de DatabaseGrowthIncrement. Si DatabaseGrowthIncrement est défini sur zéro, la préallocation est désactivée. L’espace pour les fichiers fantômes de la base de données n’est pas préalloué.
La préallocation est également désactivée si l’option « No reserve » est définie pour la base de données.
Remarque : la préallocation permet également d’éviter les corruptions en cas de manque d’espace disque - dans ce cas, il y a de fortes chances que la base de données dispose de suffisamment d’espace préalloué pour fonctionner jusqu’à ce que l’administrateur libère de l’espace disque.
Auteur : Vlad Khorsun,