VACUUM et ANALYZE sont les deux opérations de maintenance de base de données PostgreSQL les plus importantes.
Un vide est utilisé pour récupérer l'espace occupé par les "tuples morts" dans une table. Un tuple mort est créé lorsqu'un enregistrement est supprimé ou mis à jour (une suppression suivie d'une insertion). PostgreSQL ne supprime pas physiquement l'ancienne ligne de la table, mais y place un "marqueur" afin que les requêtes ne renvoient pas cette ligne. Lorsqu'un processus de vide s'exécute, l'espace occupé par ces tuples morts est marqué comme réutilisable par d'autres tuples.
Une opération "analyser" fait ce que son nom l'indique - elle analyse le contenu des tables d'une base de données et collecte des statistiques sur la distribution des valeurs dans chaque colonne de chaque table. Le moteur de requête PostgreSQL utilise ces statistiques pour trouver le meilleur plan de requête. Au fur et à mesure que des lignes sont insérées, supprimées et mises à jour dans une base de données, les statistiques des colonnes changent également. ANALYZE – exécuté manuellement par le DBA ou automatiquement par PostgreSQL après un autovacuum – garantit que les statistiques sont à jour.
Bien qu'ils semblent relativement simples, dans les coulisses, l'aspiration et l'analyse sont deux processus complexes. Heureusement, les administrateurs de bases de données n'ont pas à se soucier de leurs composants internes. Cependant, ils sont souvent confus quant à l'exécution manuelle de ces processus ou à la définition des valeurs optimales pour les paramètres de configuration.
Dans cet article, nous partagerons quelques bonnes pratiques pour VACUUM et ANALYZE.
Astuce 1 : n'exécutez pas de VIDE manuel ou d'ANALYSE sans raison
Le vidage PostgreSQL (vide automatique ou vide manuel) minimise les gonflements de table et empêche le bouclage de l'ID de transaction. Autovacuum ne récupère pas l'espace disque occupé par les tuples morts. Cependant, l'exécution d'un VACUUM FULL commande le fera. VACUUM FULL a cependant une implication sur les performances. La table cible est exclusivement verrouillée pendant l'opération, empêchant même les lectures sur la table. Le processus effectue également une copie complète de la table, ce qui nécessite de l'espace disque supplémentaire lors de son exécution. Nous vous recommandons de ne pas exécuter VACUUM FULL à moins qu'il y ait un pourcentage très élevé de gonflement et que les requêtes souffrent beaucoup. Nous vous recommandons également d'utiliser les périodes d'activité de base de données la plus faible.
Il est également recommandé de ne pas exécuter trop souvent de vidages manuels sur l'ensemble de la base de données ; la base de données cible pourrait déjà être aspirée de manière optimale par le processus d'autovacuum. Par conséquent, un vide manuel peut ne pas supprimer les tuples morts, mais entraîner des charges d'E/S inutiles ou des pics de CPU. Si nécessaire, les aspirateurs manuels ne doivent être exécutés que table par table lorsque cela est nécessaire, comme de faibles ratios de rangées vivantes par rapport aux rangées mortes ou de grands écarts entre les aspirateurs automatiques. De plus, les aspirateurs manuels doivent être exécutés lorsque l'activité de l'utilisateur est minimale.
Autovacuum tient également à jour les statistiques de distribution des données d'une table (il ne les reconstruit pas). Lorsqu'il est exécuté manuellement, le ANALYSE La commande reconstruit en fait ces statistiques au lieu de les mettre à jour. Encore une fois, la reconstruction des statistiques lorsqu'elles sont déjà mises à jour de manière optimale par un autovacuum régulier peut entraîner une pression inutile sur les ressources système.
Le moment où vous devez exécuter ANALYZE manuellement est immédiatement après le chargement en masse des données dans la table cible. Un grand nombre (même quelques centaines) de nouvelles lignes dans une table existante faussera considérablement la distribution des données de ses colonnes. Les nouvelles lignes rendront toutes les statistiques de colonne existantes obsolètes. Lorsque l'optimiseur de requête utilise de telles statistiques, les performances des requêtes peuvent être très lentes. Dans ces cas, exécuter la commande ANALYZE immédiatement après un chargement de données pour reconstruire complètement les statistiques est une meilleure option que d'attendre que l'autovacuum se déclenche.
Astuce 2 :Ajustez le seuil de vide automatique
Il est essentiel de vérifier ou d'ajuster l'autovacuum et d'analyser les paramètres de configuration dans le postgresql.conf fichier ou dans des propriétés de table individuelles pour trouver un équilibre entre autovacuum et gain de performances.
PostgreSQL utilise deux paramètres de configuration pour décider quand lancer un autovacuum :
- autovacuum_vacuum_threshold :ceci a une valeur par défaut de 50
- autovacuum_vacuum_scale_factor :ceci a une valeur par défaut de 0.2
Ensemble, ces paramètres indiquent à PostgreSQL de démarrer un autovacuum lorsque le nombre de lignes mortes dans une table dépasse le nombre de lignes dans cette table multiplié par le facteur d'échelle, plus le seuil de vide. En d'autres termes, PostgreSQL lancera l'autovacuum sur une table lorsque :
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
Pour les petites et moyennes tables, cela peut suffire. Par exemple, pour un tableau de 10 000 lignes, le nombre de lignes mortes doit être supérieur à 2 050 ((10 000 x 0,2) + 50) avant qu'un autovacuum ne démarre.
Toutes les tables d'une base de données ne connaissent pas le même taux de modification des données. Habituellement, quelques tables volumineuses subiront des modifications de données fréquentes et, par conséquent, auront un nombre plus élevé de lignes mortes. Les valeurs par défaut peuvent ne pas fonctionner pour ces tables. Par exemple, avec les valeurs par défaut, une table avec 1 million de lignes devra avoir plus de 200 050 lignes mortes avant qu'un autovacuum ne démarre ((1 000 000 x 0,2) + 50). Cela peut signifier des intervalles plus longs entre les autovacuums, des durées d'autovacuum de plus en plus longues, et pire encore, l'autovacuum ne fonctionne pas du tout si des transactions actives sur la table la verrouillent.
Par conséquent, l'objectif doit être de définir ces seuils sur des valeurs optimales afin que le vide automatique puisse se produire à intervalles réguliers et ne prenne pas beaucoup de temps (et n'affecte pas les sessions utilisateur) tout en maintenant le nombre de lignes mortes relativement bas.
Une approche consiste à utiliser l'un ou l'autre paramètre. Ainsi, si nous définissons autovacuum_vacuum_scale_factor sur 0 et que nous définissons à la place autovacuum_vacuum_threshold sur, disons, 5 000, une table sera automatiquement évacuée lorsque son nombre de lignes mortes est supérieur à 5 000.
Astuce 3 :Ajustez le seuil d'analyse automatique
Semblable à l'autovacuum, l'analyse automatique utilise également deux paramètres qui décident quand l'autovacuum déclenchera également une analyse automatique :
- autovacuum_analyze_threshold :ceci a une valeur par défaut de 50
- autovacuum_analyze_scale_factor :ceci a une valeur par défaut de 0.1
Comme autovacuum, le paramètre autovacuum_analyze_threshold peut être défini sur une valeur qui dicte le nombre de tuples insérés, supprimés ou mis à jour dans une table avant le démarrage d'une analyse automatique. Nous vous recommandons de définir ce paramètre séparément sur les tables volumineuses et à transactions élevées. La configuration de la table remplacera les valeurs de postgresql.conf.
L'extrait de code ci-dessous montre la syntaxe SQL pour modifier le paramètre autovacuum_analyze_threshold pour une table.
ALTER TABLE <table_name> SET (autovacuum_analyze_threshold = <threshold rows>)
Astuce 4 :ajustez les travailleurs de l'aspirateur automatique
Un autre paramètre souvent négligé par les DBA est autovacuum_max_workers , qui a une valeur par défaut de 3. Autovacuum n'est pas un processus unique, mais un certain nombre de threads de vide individuels exécutés en parallèle. La raison de la spécification de plusieurs nœuds de calcul est de s'assurer que l'aspiration de grandes tables ne retarde pas l'aspiration de petites tables et de sessions utilisateur. Le paramètre autovacuum_max_workers indique à PostgreSQL d'augmenter le nombre de threads de travail autovacuum pour effectuer le nettoyage.
Une pratique courante des DBA PostgreSQL consiste à augmenter le nombre maximal de threads de travail dans l'espoir d'accélérer l'autovacuum. Cela ne fonctionne pas car tous les threads partagent le même autovacuum_vacuum_cost_limit , qui a une valeur par défaut de 200. Chaque thread autovacuum se voit attribuer une limite de coût à l'aide de la formule ci-dessous :
individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers
Le coût du travail effectué par un thread autovacuum est calculé à l'aide de trois paramètres :
- vacuum_cost_page_hit :ceci a une valeur par défaut de 1
- vacuum_cost_page_miss :ceci a une valeur par défaut de 10
- vacuum_cost_page_dirty :la valeur par défaut est 20
Voici ce que signifient ces paramètres :
- Lorsqu'un thread de vide trouve la page de données qu'il est censé nettoyer dans le tampon partagé, le coût est de 1.
- Si la page de données n'est pas dans le tampon partagé, mais dans le cache du système d'exploitation, le coût sera de 10.
- Si la page doit être marquée comme sale parce que le thread vacuum a dû supprimer des lignes mortes, le coût sera de 20.
Un nombre accru de threads de travail réduira la limite de coût pour chaque thread. Comme chaque thread se voit attribuer une limite de coût inférieure, il s'endormira plus souvent car le seuil de coût est facilement atteint, ce qui ralentit finalement l'ensemble du processus de vide. Nous vous recommandons d'augmenter le autovacuum_vacuum_cost_limit à une valeur plus élevée, comme 2000, puis d'ajuster le nombre maximum de threads de travail.
Une meilleure méthode consiste à ajuster ces paramètres pour des tables individuelles uniquement lorsque cela est nécessaire. Par exemple, si le vide automatique d'une grande table transactionnelle prend trop de temps, la table peut être temporairement configurée pour utiliser sa propre limite de coût de vide et ses propres délais de coût. La limite de coût et le délai remplaceront les valeurs à l'échelle du système définies dans postgresql.conf.
L'extrait de code ci-dessous montre comment configurer des tables individuelles.
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>) ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)
L'utilisation du premier paramètre garantira que le thread autovacuum affecté à la table effectuera plus de travail avant de se mettre en veille. Réduire le autovacuum_vacuum_cost_delay signifiera également que le fil dort moins longtemps.
Réflexions finales
Comme vous pouvez le constater, la modification des paramètres de configuration pour le vide et l'analyse est simple, mais elle nécessite d'abord une observation attentive. Chaque base de données est différente en termes de taille, de modèle de trafic et de taux de transactions. Nous recommandons aux administrateurs de base de données de commencer par rassembler suffisamment d'informations sur leur base de données avant de modifier les paramètres ou de déployer un régime manuel de vide/analyse. Ces informations pourraient être :
- Nombre de lignes dans chaque tableau
- Nombre de tuples morts dans chaque table
- L'heure du dernier vide pour chaque table
- L'heure de la dernière analyse pour chaque table
- Le taux d'insertion/mise à jour/suppression de données dans chaque table
- Le temps pris par l'autovacuum pour chaque table
- Avertissements concernant les tables qui ne sont pas aspirées
- Performances actuelles des requêtes les plus critiques et des tables auxquelles elles accèdent
- Performance des mêmes requêtes après un aspirateur/analyse manuel
À partir de là, les DBA peuvent sélectionner quelques tables « pilotes » pour commencer à optimiser. Ils peuvent commencer à modifier les propriétés d'aspiration/d'analyse des tables et vérifier les performances. PostgreSQL est un moteur de base de données intelligent. Les DBA trouveront souvent qu'il est probablement préférable de laisser PostgreSQL faire le nettoyage et l'analyse plutôt que de les faire manuellement.