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 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 :

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

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.

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 :

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

  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*taille de page*nombre_de_bases < 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 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

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 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 :

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

Il est préférable d’utiliser cette construction à la place

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

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 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] !