23 autres façons d’accélérer Firebird
Alexey Kovyazin, IBSurgeon, [email protected], 08-Jan-2019
Traductions : Portugais
Pourquoi « 23 de plus » ?
Certains d’entre vous se souviennent de l’article « 45 façons d’accélérer Firebird », publié en mai 2016. Il est maintenant temps de publier la prochaine série d’astuces et de conseils, basée principalement sur l’expérience d’optimisation et de maintenance des bases de données et serveurs Firebird avec un nombre élevé de connexions (1000+).
1. Définir les options d’alimentation sur Haute performance dans Windows Server 2016 et 2019
Par défaut, Windows Server a un plan d’alimentation défini sur « Équilibré », ce qui ne convient pas aux serveurs de bases de données. Définissez-le sur « Haute performance » et gagnez environ +20 % de performances pour les opérations gourmandes en CPU. Cela peut être défini en ligne, sans redémarrage ni reboot. L’image ci-dessous montre le graphique CPU, qui démontre l’avantage du plan d’alimentation « Haute performance » :

Plus de détails sur nos tests avec les plans d’alimentation Windows peuvent être trouvés ici.
2. Activer « Autoriser le service à interagir avec le bureau » sur Classic pour Windows
Si vous utilisez Firebird avec l’architecture Classic sur Windows, activez la case à cocher « Autoriser le service à interagir avec le bureau ». Sans ce paramètre, la ressource « tas de bureau » est limitée par Windows, et Firebird ne peut pas ouvrir plus de 250-300 connexions (selon les métadonnées de la base de données et la consommation mémoire associée) - il y aura une erreur de mémoire insuffisante.

3. Attention : Contrôleur de domaine
Le problème est que Windows avec le rôle Contrôleur de domaine désactive le cache d’écriture sur le disque contenant la base de données Active Directory.
Cela affecte Firebird de diverses manières (ainsi que d’autres applications, bien sûr), et cela démontre des performances nettement inférieures à celles des serveurs sans rôles Active Directory.
Veuillez noter que ce problème affecte des versions Windows populaires telles que Windows Small Business Server 2011, ainsi que d’autres versions avec DC.
4. Augmenter la limite « max open files » sur Linux
Si vous utilisez Linux comme serveur de bases de données, n’oubliez pas d’ajuster les limites pour Firebird. Vérifiez les limites de votre processus Firebird (SuperServer ou SuperClassic) avec la commande suivante :
cat /proc//limits
et faites attention à la ligne concernant le nombre maximal de fichiers ouverts.
Firebird peut utiliser jusqu’à 4 descripteurs par connexion, et si vous avez quelque chose comme ceci :
Max open files 4096 4096 files
cela signifie que le nombre total de connexions servies par le processus Firebird sera limité à environ 1000.
Veuillez noter - si vous avez 4 bases de données sur le serveur, la connexion pour chaque base de données est comptée.
Définissez plus - je recommande 65535.
N’oubliez pas de vérifier à nouveau après le redémarrage du processus Firebird : si cela a été appliqué ou non.
Pour l’architecture Classic, il est nécessaire de vérifier et d’augmenter les limites pour l’utilisateur « firebird ».
5. Utilisez un Linux moderne
Oui, je comprends que ce conseil est trivial, mais j’ai vu de nombreuses fois une bonne amélioration des performances après la migration de CentOS 6 vers 7, d’Ubuntu 12 vers 16 (sur le même matériel !), donc c’est maintenant une recommandation incontournable pour les serveurs de bases de données avec plus de 250-300 connexions. Un Linux moderne est un prérequis avant d’autres étapes d’optimisation.
Versions Linux recommandées : CentOS 7.x et Ubuntu 16, 18.
6. Réserver 40 % de RAM pour le cache de fichiers sous Windows
Le gestionnaire de mémoire du système d’exploitation a des implications concernant l’allocation mémoire, et, par défaut, Windows exige 40 % de la RAM pour le cache de fichiers.
Malheureusement, le pauvre outil Gestionnaire des tâches Windows affiche la mémoire utilisée pour le cache de fichiers comme « libre », et certains administrateurs essaient de faire consommer toute cette mémoire libre à Firebird, donc ils définissent le paramètre DefaultDBCachePage dans firebird.conf à des valeurs très élevées, ce qui mène généralement à du swapping.
Utilisez toujours l’outil RAMMap pour voir l’utilisation réelle de la mémoire sous Windows.
La règle empirique pour Windows Server (dédié à l’utilisation comme serveur Firebird) est la suivante : la mémoire Firebird (Working Set) doit être inférieure à 40 % de la RAM totale. Si la taille totale des working sets pour tous les processus est supérieure à 50 %, le swap peut être démarré par Windows.
Veuillez noter : « réserver » signifie ici non seulement « ne pas définir trop de buffers de pages dans Firebird » mais aussi, et c’est important, limiter l’utilisation mémoire des autres logiciels. Par exemple, si vous avez MS Exchange ou MSSQL sur le même serveur que Firebird, assurez-vous de limiter leurs appétits mémoire.
Si vous êtes intéressé par les détails, j’ai enregistré un webinaire consacré à la gestion de la mémoire dans Firebird :
- Partie 1. https://www.youtube.com/watch?v=ZBmLgbYt4aM
- Partie 2, https://www.youtube.com/watch?v=-1.DF2FnU-A
7. Réserver 30 % de RAM pour le cache de fichiers sous Linux
Linux fonctionne avec le cache de fichiers d’une manière différente de Windows, et, en général, la quantité de RAM utilisée pour le cache de fichiers peut être nettement inférieure à celle de Windows, sans dégradation notable des performances de Firebird. Cependant, pour garantir des performances élevées du système avec un nombre élevé de connexions, surtout en Classic et SuperClassic, une bonne idée sera de réserver 30 % de la RAM pour le cache de fichiers.
8. Utiliser irqbalance sur Linux
irqbalance améliore souvent les performances de Firebird et l’équilibrage de charge CPU sur les serveurs avec un nombre élevé de cœurs.
9. Pour les machines virtuelles - attention à la sur-allocation mémoire
Une machine virtuelle peut être configurée pour avoir plus de mémoire que ce qui existe physiquement sur la machine hôte - avec une fonctionnalité connue sous le nom de sur-allocation mémoire (le nom peut être différent selon les systèmes de virtualisation). Cela signifie qu’en cas de pic de consommation mémoire (sur la VM avec le serveur de bases de données ou sur la VM voisine), le swap peut démarrer, ce qui entraînera des délais significatifs. Pour une VM haute performance destinée à un serveur de bases de données, toute la mémoire doit être statique.
10. Pour les machines virtuelles - vérifiez les limites de la VM
Souvent, les VM sont créées avec des limites CPU et IO par défaut, qui peuvent être très basses, comme 50 IOPS et 10 % de CPU. Vérifiez les paramètres de votre VM serveur et supprimez toutes les limites - un serveur de bases de données haute performance doit avoir tout le CPU, la bande passante et les IO possibles.
11. Nettoyer les fichiers temporaires de Firebird
Firebird crée de nombreux fichiers temporaires pour diverses opérations : tri, traitement des BLOB, traçage. Ces fichiers sont stockés aux emplacements suivants : sur Windows C:\ProgramData\firebird, sur Linux / tmp / firebird
Normalement, ces fichiers doivent être nettoyés automatiquement, cependant, parfois cela ne se produit pas (par exemple, en cas de redémarrage du serveur).
Vérifiez ces dossiers périodiquement et nettoyez les anciens fichiers - il peut y avoir plusieurs Go de fichiers obsolètes fb_NNN, et leur nettoyage libérera de l’espace sur le disque système.
12. N’oubliez pas d’activer le cache de fichiers avec un grand cache Firebird
Comme vous le savez, le cache Firebird (également appelé « page buffers ») est spécifié par le paramètre DefaultDBCachePages dans firebird.conf/databases.conf, ou directement dans l’en-tête de la base de données.
Dans Firebird 3 SuperServer, la taille de ce cache peut être définie très haute, mais il est important de se souvenir d’un autre paramètre : FileSystemCacheThreshold.
Si FileSystemCacheThreshold est inférieur à DefaultDBCachePages ou aux page buffers, le cache de fichiers du système d’exploitation ne sera pas utilisé, ce qui peut entraîner des problèmes de performances.
Dans 99 % des cas, il est préférable d’avoir le cache de fichiers activé.
Pour garantir cela, définissez toujours les paramètres selon la règle suivante :
- DefaultDBCachePages = X
- FileSystemCacheThreshold = X+ N, N>1
Il existe de rares cas où la désactivation du cache de fichiers améliore les performances - si vous avez un tel exemple, veuillez me contacter - [email protected] !
13. Accélérer la base de données de sécurité
Chaque connexion à la base de données Firebird établit une connexion à la base de données de sécurité (security3.fdb dans le cas de Firebird 3), et effectue plusieurs lectures et écritures (pages de transaction, page d’en-tête). Si vous avez des connexions fréquentes, les performances de votre base de données de sécurité peuvent devenir un problème.
Au minimum, vous pouvez faire ce qui suit :
- Augmenter les page buffers pour securityN.fdb (l’optimum empirique est de 256 buffers)
- Déplacer security3.fdb sur un disque rapide (c’est une fonctionnalité standard dans Firebird 3, dans 2.5 cela nécessitera une réinstallation)
Ensuite, vous pouvez définir Forced Writes sur OFF pour la base de données de sécurité - le faible risque de corruption n’est pas un problème dans ce cas.
La manière la plus radicale est de rendre la base de données de sécurité en lecture seule - cela éliminera toutes les écritures vers elle.
Si vous ne changez pas souvent les utilisateurs dans la base de données de sécurité, c’est la meilleure solution.
14. Essayez SuperClassic sur Firebird 3
Dans Firebird 3, l’architecture SuperServer a été fortement vantée comme la solution de performance ultime, mais il existe certains types de charge qui démontrent de meilleures performances avec SuperClassic (mais pas Classic - il fonctionne toujours plus lentement que SuperServer/SuperClassic).
Comment mener cette expérience en toute sécurité ? Suivez les étapes ci-dessous :
Pour essayer SuperClassic
- Définissez dans firebird.conf
- ServerMode=SuperClassic
- DefaultDbCachePages=1024
- gfix -buff 0
- Redémarrez Firebird
Pour revenir à SuperServer
- Définissez dans firebird.conf
- ServerMode=SuperServer
- DefaultDbCachePages=N # N*taille de page*nombre_de_bases < 25 % RAM
- FileSystemCacheThreshold = N+1
- gfix -buff 0
- Redémarrez Firebird
Veuillez m’écrire ([email protected]) au sujet des résultats de l’expérience, je suis intéressé de voir les résultats.
15. Grande base de données ? Augmentez la taille de page
Par défaut, les bases de données Firebird ont les tailles de page suivantes :
- 2.5 - 4096 octets
- 3.0 - 8192 octets
Cependant, la taille de page maximale est de 16K (dans 4.0 - 32K).
Pour les bases de données de plus de 100 Go, dans 95 % des cas, il est préférable d’avoir la taille de page la plus élevée disponible, afin de :
- Diminuer la profondeur des index. Il est recommandé d’avoir des index avec une profondeur inférieure ou égale à 3. Les index avec une profondeur de 4 et 5 seront beaucoup plus lents
- Augmenter l’utilisation de la RAM. Le cache Firebird est spécifié en pages, 1000 pages avec une taille de page de 8K représenteront 8 Mo de mémoire réelle, et avec 16K - 16 Mo.
- Diminuer le nombre de pages système. Cela accélérera l’accès aux enregistrements des grandes tables (moins de sauts pointeur-pointeur-page de données), et aide à la préparation des grandes requêtes SQL. Pour augmenter la taille de page de la base de données, la base de données doit être sauvegardée avec l’outil gbak puis restaurée avec le paramètre -page ( gbak -c -page 16384).
Veuillez noter : si vous avez une base de données avec de nombreux petits blobs, l’augmentation de la taille de page peut soit diminuer la fragmentation, soit l’augmenter, et il est difficile de prédire si cela augmentera ou diminuera les performances.
16. N’utilisez pas le flag no_reserve
Le flag no_reserve fait en sorte que Firebird ne réserve pas d’espace libre (30 %) sur les pages de données pour les versions d’enregistrements possibles, qui surviennent après UPDATE ou DELETE. Ce flag permet de stocker les données de manière plus compacte (et la taille de la base de données est également moindre), mais en cas d’UPDATE/DELETE, toutes les modifications vont vers la nouvelle page de données. En conséquence, dans une base de données avec le flag no_reserve, les opérations UPDATE/DELETE sont plus lentes.
Donc, si votre base de données n’est pas en lecture seule, je recommande de supprimer le flag no_reserve.
Comment vérifier s’il est défini ou non - voir la ligne Attributes dans la sortie de
gstat -h database
Comment le désactiver :
gfix -use reserve database
Après cette commande, les nouvelles pages de données seront créées avec un espace réservé.
Cependant, pour obtenir l’effet complet, il est nécessaire de sauvegarder la base de données avec gbak puis de la restaurer, dans ce cas, toutes les pages de données seront avec un espace réservé.
Veuillez noter : la taille de la base de données augmentera après la suppression du flag no_reserve et la sauvegarde/restauration.
17. Définissez une taille initiale élevée pour la table de verrouillage Firebird
La table de verrouillage est le mécanisme de Firebird, qui est utilisé pour synchroniser l’accès aux objets internes du moteur.
Firebird lock table peut croître automatiquement, mais son augmentation est une opération lente, ce qui peut entraîner des micro-gels. La lock table ne peut que croître, à partir de la taille initiale (définie dans firebird.conf).
Pour éviter plusieurs cycles d’augmentation de la lock table, une bonne idée est de surveiller la taille de la lock table à la fin de la période de travail (jour, semaine, etc.), puis de la définir comme taille initiale dans firebird.conf.
LockMemSize=99999999
Pour référence : LockMemSize sur les systèmes à forte charge avec ~1000 utilisateurs est généralement inférieur à 200 Mo.
18. Utiliser fb_lock_print pour compter le nombre de connexions à la base de données
Obtenir le nombre de connexions à la base de données est une tâche fréquente pour les développeurs de bases de données : cela peut être nécessaire à des fins de licence, par exemple.
Souvent, les développeurs utilisent la requête SELECT count(*) FROM MON$ATTACHMENTS pour obtenir cette valeur, mais ce n’est pas la méthode optimale : des requêtes fréquentes sur les tables MON$ peuvent être une charge pour la base de données, il est donc préférable d’utiliser l’alternative :
Exécutez
fb_lock_print -d nom_de_la_base | alias
et vérifiez la valeur Owners - elle affichera le nombre actuel de connexions à la base de données.
19. Éviter les LEFT JOIN inutiles
Je vois souvent des requêtes avec une construction comme celle-ci :
T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition
Essentiellement, la condition sur T2 exclut les NULL du résultat du LEFT JOIN T2, il est donc possible de changer LEFT JOIN en INNER JOIN - cela n’affectera pas le résultat de la requête.
INNER JOIN donne plus de liberté à l’optimiseur de Firebird, et dans les versions modernes de Firebird, il est bien mieux optimisé que LEFT.
Cela a particulièrement du sens dans les cas suivants :
- Aucune condition pour T1 dans la clause WHERE
- T2 est une petite table
20. Éviter les comptages de records inutiles
Une autre erreur courante dans les requêtes complexes et les procédures stockées est d’utiliser select count() juste pour vérifier l’existence d’un enregistrement.
La requête suivante lira tous les enregistrements selon condition1 :
(select count(*)…. where condition11) >0
Il est préférable d’utiliser cette construction à la place
Exists(select first 1 id where condition1)
Si condition1 renvoie plus d’un enregistrement, l’option proposée sera beaucoup plus rapide, car elle ne lit pas tous les enregistrements, elle s’arrête après le premier enregistrement récupéré.
21. Éviter les tris inutiles dans les procédures stockées
Le tri des résultats de requêtes à l’intérieur d’une procédure stockée doit être justifié par la logique métier.
Par exemple, dans l’exemple de procédure stockée ci-dessous, la clause ORDER BY est inutile du point de vue de la logique métier, mais elle ajoute une opération de tri inutile.
create or alter procedure NEW_PROCEDURE
returns (
SUMX double precision)
as
declare variable _amount double precision;
begin
for select T1.amount from Table1 t1 where ....
order by id
into :_amount
do
begin
sumx=sumx+_amount
end;
suspend;
end
Vérifiez votre code PSQL pour des situations similaires et supprimez les ORDER BY inutiles (ainsi que distinct et UNION).
22. Ne pas garder les requêtes à l’état préparé sans nécessité
Nous voyons souvent 500 à 1000 instructions préparées dans chaque connexion (cela peut être vérifié avec les requêtes MON$).
La grande majorité d’entre elles ne s’exécute qu’une seule fois, puis elles restent simplement dans la RAM, augmentant la taille de travail de Firebird et ralentissant les requêtes MON$.
La recommandation est de garder les requêtes SQL à l’état préparé uniquement si elles sont destinées à être lancées plusieurs fois, ou si leur temps de préparation est important (cela peut être le cas pour de très grandes requêtes avec beaucoup de jointures et d’accès à de grandes tables).
23. Toujours fermer les requêtes avec un grand tri
Tant qu’une requête SQL avec tri (ORDER BY, GROUP BY, UNION, distinct) n’est pas fermée, Firebird conserve les enregistrements triés en mémoire. La taille de la mémoire allouée pour le tri est définie par le paramètre TempCacheLimit dans firebird.conf, par défaut elle est de 64 Mo.
Même avec un TempCacheLimit augmenté, les requêtes de longue durée avec un grand nombre d’enregistrements triés consommeront éventuellement toute la quantité allouée, et par conséquent, le tri ira dans les fichiers temporaires (c’est-à-dire sur le disque). Cela peut entraîner un ralentissement significatif.
La recommandation est de fermer toutes ces requêtes en temps opportun.
Des questions ?
N’hésitez pas à me contacter pour toute question : [email protected] !