Cette page a été traduite automatiquement. Lisez l'original en anglais. English

Bibliothèque IBSurgeon

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 Ways To Speed Up Firebird », publié en mai 2016. Il est maintenant temps de publier la série suivante de conseils et astuces, principalement basée sur l’expérience d’optimisation et de maintenance des bases de données et des serveurs Firebird avec un grand nombre de connexions (1000+).

1. Réglez les options d’alimentation sur Haute performance dans Windows Server 2016 et 2019

Par défaut, Windows Server a un plan d’alimentation réglé sur « Équilibré », ce qui ne convient pas aux serveurs de bases de données. Réglez-le sur « Haute performance » et gagnez environ +20 % de performance pour les opérations gourmandes en CPU. Cela peut être réglé 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. Activez « Interagir avec le bureau » sur Classic pour Windows

Si vous utilisez Firebird avec l’architecture Classic sous Windows, activez la case à cocher « Autoriser le service à interagir avec le bureau ». Sans ce réglage, la ressource « desktop heap » est limitée par Windows, et Firebird ne peut pas ouvrir plus de 250-300 connexions (cela dépend des métadonnées de la base de données et de la consommation mémoire associée) - il y aura une erreur Out Of Memory.

3. Attention : contrôleur de domaine

Le problème est que Windows avec le rôle de 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 il démontre des performances nettement moins bonnes que sur les serveurs sans rôles Active Directory.

Veuillez noter que ce problème affecte des versions populaires de Windows comme Windows Small Business Server 2011, ainsi que d’autres versions avec DC.

4. Augmentez la limite « max open files » sous Linux

Si vous utilisez Linux comme serveur de base 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 :

Code
cat /proc//limits

et faites attention à la ligne indiquant le nombre maximal de fichiers ouverts.

Firebird peut utiliser jusqu’à 4 handles par connexion, et si vous avez quelque chose comme ceci :

Code
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.

Réglez une valeur plus élevée - je recommande 65535.

N’oubliez pas de vérifier à nouveau après le redémarrage du processus Firebird : a-t-elle été appliquée 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 la recommandation indispensable pour les serveurs de bases de données avec plus de 250-300 connexions. Un Linux moderne est un prérequis avant toute autre étape d’optimisation.

Versions de Linux recommandées : CentOS 7.x et Ubuntu 16, 18.

6. Réservez 40 % de la RAM pour le cache de fichiers sous Windows

Le gestionnaire de mémoire du système d’exploitation a des implications concernant l’allocation de mémoire, et, par défaut, Windows exige 40 % de la RAM pour le cache de fichiers.

Malheureusement, le pauvre outil qu’est le Gestionnaire des tâches de 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 par Firebird, ils règlent donc le paramètre DefaultDBCachePage dans firebird.conf à des valeurs très élevées, ce qui conduit généralement au 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’usage comme serveur Firebird) est la suivante : la mémoire de Firebird (Working Set) doit être inférieure à 40 % de la RAM totale. Si la taille totale des working sets de tous les processus dépasse 50 %, le swap peut être déclenché par Windows.

Veuillez noter : « réserver » ici ne signifie pas seulement « ne pas définir trop de tampons de pages dans Firebird » mais aussi, ce qui est important, limiter l’utilisation de la mémoire par les 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 de mémoire.

Si vous souhaitez connaître les détails, j’ai enregistré le webinaire consacré à la gestion de la mémoire dans Firebird :

7. Réservez 30 % de la 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 sous Windows, sans dégradation notable des performances de Firebird. Cependant, pour garantir de hautes performances du système avec un grand nombre de connexions, en particulier sur Classic et SuperClassic, il est judicieux de réserver 30 % de la RAM pour le cache de fichiers.

8. Utilisez irqbalance sous Linux

irqblalnce améliore souvent les performances de Firebird et l’équilibrage de charge CPU sur les serveurs avec un grand nombre de cœurs.

9. Pour les machines virtuelles - attention au Memory Overcommit

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 Memory Overcommit (le nom peut être différent selon les systèmes de virtualisation). Cela signifie qu’en cas de pic de consommation de mémoire (sur la VM avec le serveur de base de données ou sur la VM voisine), le swap peut démarrer, ce qui entraînera des délais importants. Pour une VM haute performance destinée à un serveur de base 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 base de données haute performance doit disposer de tout le CPU, de la bande passante et des IO possibles.

11. Nettoyez 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 : sous Windows C:\ProgramData\firebird, sous Linux / tmp / firebird

Normalement, ces fichiers devraient être nettoyés automatiquement, cependant, parfois cela ne se produit pas (par exemple, en cas de redémarrage du serveur).

Vérifiez périodiquement ces dossiers et nettoyez les anciens fichiers - il peut y avoir plusieurs Go de fichiers fb_NNN obsolètes, 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 (aussi 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 élevée, mais il est important de se rappeler 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 performance.

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érez la base de données de sécurité

Chaque connexion à la base de données Firebird établit la 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 :

  • Augmentez les page buffers pour securityN.fdb (l’optimum empirique est de 256 tampons)
  • Déplacez security3.fdb vers un disque rapide (c’est une fonctionnalité standard dans Firebird 3, dans 2.5 cela nécessitera une réinstallation)

Ensuite, vous pouvez régler Forced Writes OFF pour la base de données de sécurité - la faible probabilité 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 celle-ci.

Si vous ne modifiez 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 certains types de charge démontrent de meilleures performances avec SuperClassic (mais pas Classic - qui fonctionne toujours plus lentement que SuperServer/SuperClassic).

Comment mener cette expérience de manière sûre ? Suivez les étapes ci-dessous :

Pour essayer SuperClassic

  1. Définissez dans firebird.conf
  2. ServerMode=SuperClassic
  3. DefaultDbCachePages=1024
  4. gfix -buff 0
  5. Redémarrez Firebird

Pour revenir à SuperServer

  1. Définissez dans firebird.conf
  2. ServerMode=SuperServer
  3. DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
  4. FileSystemCacheThreshold = N+1
  5. gfix -buff 0
  6. 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 de profondeur inférieure ou égale à 3. Les index de profondeur 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 beaucoup de petits blobs, augmenter 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 l’indicateur no_reserve

L’indicateur no_reserve fait que Firebird ne réserve pas d’espace libre (30 %) sur les pages de données pour les éventuelles versions d’enregistrements, qui surviennent après UPDATE ou DELETE. Cet indicateur permet de stocker les données de manière plus compacte (et la taille de la base de données est également réduite), mais en cas de UPDATE/DELETE, toutes les modifications vont vers la nouvelle page de données. En conséquence, dans la base de données avec l’indicateur 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 l’indicateur no_reserve.

Comment vérifier s’il est défini ou non - voir la ligne Attributes dans la sortie de

Code
gstat -h database

Comment le désactiver :

Code
gfix -use reserve database

Après cette commande, les nouvelles pages de données seront créées avec de l’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 de l’espace réservé.

Veuillez noter : la taille de la base de données augmentera après la suppression de l’indicateur no_reserve et la sauvegarde/restauration.

17. Définissez une taille initiale élevée pour la table de verrous de Firebird

La table de verrous est le mécanisme de Firebird, qui est utilisé pour synchroniser l’accès aux objets internes du moteur.

La table des verrous de Firebird peut croître automatiquement, mais son augmentation est une opération lente, qui peut entraîner des micro-blocages. La table des verrous ne peut que croître, à partir de sa taille initiale (définie dans firebird.conf).

Pour éviter plusieurs cycles d’augmentation de la table des verrous, une bonne idée est de surveiller la taille de la table des verrous à 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 votre information : LockMemSize sur les systèmes à forte charge avec ~1000 utilisateurs est généralement inférieur à 200 Mo.

18. Utilisez 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 : les requêtes fréquentes sur les tables MON$ peuvent représenter une charge pour la base de données, il vaut donc mieux utiliser l’alternative :

Exécutez

fb_lock_print -d database_name | alias

et vérifiez la valeur Owners - elle affichera le nombre actuel de connexions à la base de données.

19. Évitez 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 de la sortie du LEFT JOIN T2, il est donc possible de transformer le LEFT JOIN en INNER JOIN - cela n’affectera pas le résultat de la requête.

INNER JOIN donne plus de liberté à l’optimiseur 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. Évitez le comptage inutile d’enregistrements

Une autre erreur courante dans les requêtes complexes sur la base de données et les procédures stockées est d’utiliser select count() juste pour vérifier l’existence de l’enregistrement.

La requête suivante lira tous les enregistrements selon condition1 :

Code
(select count(*)…. where condition11) >0

Utilisez plutôt cette construction

Code
Exists(select first 1 id where condition1)

Si condition1 renvoie plus d’un enregistrement, l’option proposée sera bien plus rapide, car elle ne lit pas tous les enregistrements, elle s’arrête après le premier enregistrement récupéré.

21. Évitez le tri inutile dans les procédures stockées

L’ordonnancement des résultats de la requête à l’intérieur de la 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 superflue.

Code
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 gardez pas les requêtes à l’état préparé sans nécessité

Souvent, nous voyons 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écutent qu’une seule fois, puis elles restent simplement en RAM, ce qui agrandit l’ensemble de travail de Firebird et ralentit 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 de nombreuses fois, ou si leur temps de préparation est important (cela peut être le cas pour de très grosses requêtes avec beaucoup de jointures et d’accès à d’énormes tables).

23. Fermez toujours les requêtes avec un tri important

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 au tri est définie par le paramètre TempCacheLimit dans firebird.conf, par défaut 64 Mo.

Même avec un TempCacheLimit augmenté, les requêtes de longue durée avec un grand nombre d’enregistrements triés finiront par consommer toute la quantité allouée et, par conséquent, le tri passera sur des fichiers temporaires (c’est-à-dire le disque). Cela peut entraîner une lenteur significative.

La recommandation est de fermer toutes ces requêtes en temps voulu.

Des questions ?

N’hésitez pas à me contacter pour toute question : [email protected] !