Traqueur, pénurie de mémoire vive

Rien ne va plus

Téléchargement du traqueur pour PostgreSQL 9.6 et 10
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 indiquer 0 pour des performances optimales. Ici, nous ne travaillons pas en mémoire vive et c'est la raison de la dégradation générale des performances.
      Que faire si la situation est critique et 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 : 02/07/2017