Traqueur, pénurie de mémoire vive

Rien ne va plus

Téléchargement du traqueur pour PostgreSQL 12, 13, 14, 15, 16
Téléchargement du traqueur pour PostgreSQL 11
Téléchargement du traqueur pour PostgreSQL 10
Téléchargement du traqueur pour PostgreSQL 9.6
Téléchargement du traqueur pour PostgreSQL 9.5
Téléchargement du traqueur pour PostgreSQL 9.4
Téléchargement du traqueur pour PostgreSQL 9.3
Journal des changements
Signalement de bugs via le forum
Licence identique à celle de PostgreSQL, open source type BSD
Dossier des versions

      Tout le monde se plaint aujourd’hui. Que se passe-t-il sur le serveur de base de données ? Vous lancez une session de traque, notamment avec l’option -p :

time ./traqueur.sh -p -o "pid, query" traqueur 0.06.01beta - outil de diagnostic performance pour PostgreSQL 9.6, 10 INFORMATION, pas d'options de connexions indiquees, utilisation de la base traqueur detectee ... INFORMATION, preparation de la collecte ... INFORMATION, execution de la collecte et presentation des resultats ... busy_pc | distinct_exe | pid | query | non_cpu_pc | mem_en_mo | swapped_en_mo ---------+--------------+------+--------------------------------------------------------------------+------------+-----------+--------------- 100 | 1 / 50 | 627 | select +| 90 | 0 | 15 | | | avg(taille) filter (where genre = 'M') taille_moyenne_geants, +| | | | | | avg(taille) filter (where genre = 'F') taille_moyenne_geantes, +| | | | | | avg(masse) filter (where actif) masse_moyenne_actifs, +| | | | | | avg(masse) filter (where not actif) masse_moyenne_blesses, +| | | | | | count(*) filter (where revenu > 900000) nombre_riches, +| | | | | | count(*) filter (where berserk and veteran) nombre_guerriers_fous+| | | | | | from geants; | | | 100 | 1 / 50 | 3629 | select +| 91 | 2 | 19 | | | avg(taille) filter (where genre = 'M') taille_moyenne_geants, idu+| | | | | | from geants group by idu; | | | 100 | 1 / 50 | 4393 | select +| 91 | 0 | 15 | | | avg(taille) filter (where genre = 'M') taille_moyenne_geants, +| | | | | | avg(taille) filter (where genre = 'F') taille_moyenne_geantes, +| | | | | | avg(masse) filter (where actif) masse_moyenne_actifs, +| | | | | | avg(masse) filter (where not actif) masse_moyenne_blesses, +| | | | | | count(*) filter (where revenu > 900000) nombre_riches, +| | | | | | count(*) filter (where berserk and veteran) nombre_guerriers_fous+| | | | | | from geants; | | | 100 | 1 / 50 | 4394 | select +| 91 | 0 | 15 | | | avg(taille) filter (where genre = 'M') taille_moyenne_geants, +| | | | | | avg(taille) filter (where genre = 'F') taille_moyenne_geantes, +| | | | | | avg(masse) filter (where actif) masse_moyenne_actifs, +| | | | | | avg(masse) filter (where not actif) masse_moyenne_blesses, +| | | | | | count(*) filter (where revenu > 900000) nombre_riches, +| | | | | | count(*) filter (where berserk and veteran) nombre_guerriers_fous+| | | | | | from geants; | | | 84 | 1 / 42 | 3929 | select +| 94 | 3 | 16 | | | avg(taille) filter (where genre = 'M') taille_moyenne_geants, idu+| | | | | | from geants group by idu; | | | 84 | 1 / 42 | 3930 | select +| 95 | 3 | 16 | | | avg(taille) filter (where genre = 'M') taille_moyenne_geants, idu+| | | | | | from geants group by idu; | | | 10 | 1 / 5 | 4733 | autovacuum: ANALYZE pg_catalog.pg_proc | 90 | 2 | 13 10 | 1 / 5 | 4733 | autovacuum: ANALYZE pg_catalog.pg_attribute | 94 | 2 | 13 8 | 1 / 4 | 4733 | autovacuum: VACUUM ANALYZE pg_catalog.pg_class | 95 | 2 | 13 4 | 1 / 2 | 4733 | autovacuum: ANALYZE pg_catalog.pg_depend | 100 | 2 | 13 (10 lignes) Charge CPU moyennne globale ----------------------------- 6 (1 ligne) temps_cpu_user_en_s | temps_cpu_systeme_en_s | temps_cpu_idle_en_s | temps_io_en_s ---------------------+------------------------+---------------------+--------------- 3 | 32 | 111 | 303 (1 ligne) real 1m5,271s user 0m0,280s sys 0m0,324s

Un grand classique

      Premier constat : la session de traque doit durer moins de 10 secondes et elle dure ici 65s. Les ralentissements toucheront toute activité sur ce cluster PostgreSQL.
      Si nous nous intéressons globalement à l'activité du système, nous constatons que la charge CPU est faible (6%). Le temps d'attente I/O est en revanche très important (303s).
      Si nous nous intéressons ensuite à ce qui se passe au niveau des process PostgreSQL actifs, nous constatons via la colonne swapped_en_mo que la mémoire est systématiquement swappée. En mode interactif, si l'option -b n'est pas utilisée, cette valeur est collectée une seule fois par process lors d'une session de traque mais donne tout de même une bonne indication de la situation.
      La colonne swapped_en_mo doit idéalement indiquer 0 pour des performances optimales. Il faut noter, tout de même, que la présence de mémoire swappée n'est pas toujours synonyme de performances degradées si cela reste ponctuel. Cette colonne peut indiquer que le système a swappé de la mémoire pour ce process mais le phénomène est peut-être terminé. Depuis la 7.1.0, le traqueur donne en plus la quantité de mémoire swappée pendant l'analyse pour affiner le diagnostic. Si swapped_en_mo affiche une valeur positive mais que le système ne swappe plus, ce n'est pas (ou plus) la cause des ralentissements. En revanche, si swapped_en_mo affiche une valeur positive et que le système swappe massivement, il y a lieu de s'inquiéter.
      Que faire si le serveur swappe en continu et si la situation nécessite d'agir très rapidement ? Augmenter la mémoire vive bien sûr et, si ce n'est pas possible, tenter d'être moins gourmand. Vous pouvez par exemple arrêter tout ce qui peut l’être, désactiver le parallélisme (paramètres max_parallel_workers_per_gather = 0), réduire les valeurs des paramètres liés à la mémoire comme shared_buffers, work_mem etc.

Mise à jour : 18/12/2023