Postgres al 100% di CPU per database di grandi dimensioni, Discourse 2.7.7

Ciao,

stiamo eseguendo Discourse 2.7.7 basato su Docker con un numero molto elevato di utenti. Dopo l’aggiornamento dalla versione 2.4.2 alla 2.7.7, stiamo riscontrando che alcuni processi Postgres rimangono bloccati al 100% di utilizzo della CPU. Ulteriori indagini hanno evidenziato che tali query sembrano essere la causa del problema:

discourse_prod=# select pid, datid, query from pg_stat_activity WHERE pid = '244906';
  pid   |  datid  |                         query
--------+---------+-------------------------------------------------------
 244906 | 2068583 | DELETE FROM user_badges                              +
        |         |   WHERE id IN (                                      +
        |         |     SELECT ub.id                                     +
        |         |     FROM user_badges ub                              +
        |         |     LEFT JOIN (                                      +
        |         |       SELECT id user_id, current_timestamp granted_at+
        |         | FROM users                                           +
        |         | WHERE id  IN (                                       +
        |         |        SELECT p1.user_id                             +
        |         |        FROM post_custom_fields pc                    +
        |         |        JOIN badge_posts p1 ON p1.id = pc.post_id     +
        |         |        JOIN topics t1 ON p1.topic_id = t1.id         +
        |         |        WHERE p1.user_id <> t1.user_id AND            +
        |         |                     name = 'is_accepted_answer' AND  +
        |         |             p1.user_id IN (                          +
        |         |                    SELECT user_id                    +
        |         |                    FROM posts                        +
        |         |                    WHERE TRUE OR  p1.id IN (-1)      +
        |         |             )                                        +
        |         |         GROUP BY p1.user_id                          +
        |         |         HAVING COUNT(*) > 9                          +
        |         | )                                                    +
        |         |     ) q ON q.user_id = ub.user_id                    +
        |         |                                                      +
        |         |     WHERE ub.badge_id = 103 AND q.user_id IS NULL    +
        |         |   )                                                  +
        |         |
(1 row)

Abbiamo individuato questa query che, a quanto pare, dovrebbe causare un notevole sovraccarico, non è vero?

        |         |                    SELECT user_id                    +
        |         |                    FROM posts                        +
        |         |                    WHERE TRUE OR  p1.id IN (-1)      +

Avete qualche suggerimento in merito?
Fatemelo sapere se avete bisogno di ulteriori informazioni.

Grazie,
Daniel.

Questa query sembra provenire da Jobs::BadgeGrant.

Abbiamo individuato che il problema era causato da una query SQL personalizzata in un badge utente. Quindi non si tratta di un problema upstream. Grazie.

Sospetto che vorrai anche assicurarti di eseguire vacuum e reindicizzazione come descritto nell’aggiornamento di PostgreSQL 13.