Requête causant 400% de charge CPU

Nous avons récemment des problèmes de surcharge du processeur.
Nous avons réussi à le localiser sur une requête qui continue de s’exécuter simultanément pendant des heures (voir ci-dessous).
La tâche en cours d’exécution est postmaster - une fois que tout est arrêté, le processeur est réduit jusqu’à ce qu’il soit reconstruit toutes les cinq minutes.

SELECT “users”.“id”, ARRAY_AGG(ARRAY [uccm.id, c_msg.id]) AS memberships_with_unread_messages
FROM “users”
         INNER JOIN “user_options” ON “user_options”.“user_id” = “users”.“id”
         INNER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id
         INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id
         INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id
         LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id
WHERE “user_options”.“chat_enabled” = TRUE
  AND “user_options”.“chat_email_frequency” = 1
  AND (users.last_seen_at < ‘2023 - 11 - 15 09:54:26.931723’)
  AND (c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id)
  AND (c_msg.created_at > ‘2023 - 11 - 08 10:09:26.931848’)
  AND ((uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
       (uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
       (uccm.user_id = c_mentions.user_id AND uccm.following IS true AND
        cc.chatable_type = ‘Category’

Quelqu’un peut-il aider ou suggérer une solution ?

Plus d’infos :

  • exécution de la version 3.2.0.beta4-dev, mais cela se produit depuis au moins quelques mois
  • Voici une liste des plugins que nous avons installés :

Merci !

2 « J'aime »

@andrei a récemment travaillé à l’optimisation des requêtes de chat. Cela se produit-il toujours après la mise à jour vers la dernière version ?

4 « J'aime »

J’ai travaillé sur une autre requête similaire et cette correction était locale à cette requête, donc elle n’aidera probablement pas ici. Néanmoins, cela vaut la peine de mettre à jour vers la dernière version, il peut y avoir d’autres optimisations.

2 « J'aime »

Nous sommes sur la dernière version, en effet.

Je suppose que c’était un problème de discussion lié à la requête. Y a-t-il quelque chose que nous puissions ajuster dans les paramètres pour résoudre le problème ?

1 « J'aime »

Nous avons eu un client qui a activé les mentions @all dans le chat, avec deux canaux de 16k utilisateurs. C’était amusant !
Après 19 mentions à tous, ils l’ont rapidement désactivé à nouveau. 12 heures plus tard, leur système (robuste) était toujours en charge CPU élevée.

Le problème a été résolu en supprimant les 320k enregistrements fautifs de la table des mentions

delete from chat_mentions 
where chat_message_id in (
  (select chat_message_id 
   from chat_mentions 
   group by chat_message_id having count(*) > 100)
);

mais nous étions encore perplexes quant à la raison pour laquelle cela causait autant de problèmes.
Il y avait un certain nombre d’instances de cette requête encore en cours d’exécution.

Comme les lignes avaient déjà disparu, un explain n’a pas donné de bons résultats, mais il est clair que cela causait un travail acharné. Tous les index sont en place.

1 « J'aime »

Je pense que quelqu’un a mentionné que la requête était intensive hier aussi :

2 « J'aime »

Merci - je devrais apprendre à mieux chercher sur ce forum.

1 « J'aime »

Cela ne nous a pas résolu le problème.

Nous avons également vu des messages de chat disparaître pendant quelques minutes avant de réapparaître.

En général, je pense qu’il y a beaucoup à améliorer dans le chat, bien que j’aime totalement la direction qu’il prend. Ma principale préoccupation est la façon dont un chat peut essentiellement provoquer une surcharge qui ne s’arrête pas. Nous avons désactivé la possibilité de mentionner, et cela n’a pas non plus fonctionné.

Y a-t-il un moyen d’empêcher la requête que j’ai mentionnée de revenir ? @andrei @JammyDodger

Merci d’avance.

Salut @sok777 , merci pour votre suivi — nous avons quelques ingénieurs qui étudient le problème, et nous vous tiendrons au courant ici une fois que nous aurons une mise à jour pour vous. Nous apprécions votre patience en attendant !

2 « J'aime »

Une astuce qui fonctionne bien est Admin - Personnaliser - Mots surveillés et d’ajouter les deux mentions à la liste « Censure ».

donc « tous » et « ici » avec un préfixe @ ?

Merci !

1 « J'aime »

Super. Merci !

1 « J'aime »

Une mise à jour rapide @lindsey @RGJ

Nous avons eu un message avec @all que nous avons supprimé. Cependant, cela n’a pas résolu le problème. La requête revient toutes les 5 minutes et prend une éternité, au point qu’il y a une file d’attente de nombreuses autres requêtes.
Une fois que nous avons désactivé le chat, la charge CPU est tombée à 15%. C’est fou.

Vous devez aller dans la base de données et supprimer les enregistrements de mentions

psql : delete from chat_mentions where chat_message_id = X
où X est l’ID du message que vous avez supprimé.

Une requête plus générique est décrite dans mon message ici, ajustez le nombre comme bon vous semble.

1 « J'aime »

Oui, nous avons déjà essayé cela.

Pour référence, voici nos statistiques :

utilisateurs : 239251
canaux de discussion : 2864
brouillons de discussion : 205
mentions de discussion : 155527 ->7500~
messages de discussion : 390453
fils de discussion : 25131
réactions aux messages de discussion : 5993
membres de canaux de discussion : 158480

1 « J'aime »

La seule raison pour laquelle cette requête peut prendre du temps est le grand nombre d’entrées dans la table chat_mentions. Avez-vous essayé la requête générique que j’ai postée ? Peut-être que ce n’est pas @all mais un autre grand groupe qui est mentionné.

La requête problématique recherche toutes les mentions des discussions des 7 derniers jours.

Vous devriez également arrêter toutes les instances existantes de la requête.

Oui, nous les avons tués, mais ils continuent de revenir.
Nous avons vérifié toutes les mentions supérieures à 100 et nous n’en avions aucune. Je ne suis pas sûr de la raison pour laquelle cela se produirait autrement.
Il me semble qu’il y a un problème fondamental avec la requête, mais je pourrais me tromper.

1 « J'aime »

Cette requête est probablement lente, même avec une petite quantité de mentions. Je vais travailler à la corriger.

2 « J'aime »

Super. Heureux de continuer à soutenir à partir de notre cas d’utilisation !

2 « J'aime »

@sok777 J’aurais besoin d’un peu de votre aide. J’aimerais examiner le plan de requête que Postgres utilise sur votre site. Pourriez-vous s’il vous plaît exécuter ceci sur votre base de données et partager les résultats :

EXPLAIN VERBOSE SELECT "users"."id", ARRAY_AGG(ARRAY [uccm.id, c_msg.id]) AS memberships_with_unread_messages
FROM "users"
         INNER JOIN "user_options" ON "user_options"."user_id" = "users"."id"
         INNER JOIN "group_users" ON "group_users"."user_id" = "users"."id"
         INNER JOIN "groups" ON "groups"."id" = "group_users"."group_id"
         INNER JOIN user_chat_channel_memberships uccm ON uccm.user_id = users.id
         INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id
         INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id
         LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id
WHERE "user_options"."chat_enabled" = TRUE
  AND "user_options"."chat_email_frequency" = 1
  AND (users.last_seen_at < '2023-11-27 08:00:00.0000000')
  AND (c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id)
  AND (c_msg.created_at > '2023-11-20 08:00:00.0000000')
  AND ((uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
       (uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
       (
               (uccm.user_id = c_mentions.user_id AND uccm.following IS true AND cc.chatable_type = 'Category') OR
               (cc.chatable_type = 'DirectMessage')
           )
    )
GROUP BY users.id, uccm.user_id
ORDER BY "users"."id" ASC
LIMIT 1000;
1 « J'aime »